Ref in async Task - c#

How I can to pass a reference as a parameter to Async method in Windows Store App ? I'm looking for something like this:
var a = DoThis(ref obj.value);
public async Task DoThis(ref int value)
{
value = 10;
}
But error:
Async methods cannot have ref or out parameters
Has any another way?
Note:I need to pass exactly obj.value. This method would be used by different types of objects, by same type of objects, by one object, but I will pass obj.val_1, obj.val_2 or obj.val_10. All values will be same type (for ex string)

If you don't care about a little overhead and possibly prolonged lifetime of your objects, you could emulate the ref behavior by passing a setter and a getter method to the function, like this:
public async Task DoStuff(Func<int> getter, Action<int> setter)
{
var value1 = getter();
await DoSomeOtherAsyncStuff();
setter(value1 * value1);
}
And call it like this:
await DoStuff(() => obj.Value, x => obj.Value = x);

You could directly pass the object itself and set the value of the corresponding property inside the method:
var a = DoThis(obj);
public async Task DoThis(SomeObject o)
{
o.value = 10;
}
And if you do not have such object simply write one and have the async method take that object as parameter:
public class SomeObject
{
public int Value { get; set; }
}

You can always use the Task<> class and return the desired value. Then Your code would look something like:
var a = DoThis(obj.value);
obj.value = a.Result;
public async Task<int> DoThis(int value)
{
int result = value + 10; //compute the resulting value
return result;
}
EDIT
Ok, the other way to go with this that I can think of is encapsulating the update of the given object's member in a method and then passing an action invoking this method as the task's argument, like so:
var a = DoThis(() => ChangeValue(ref obj.value));
public void ChangeValue(ref int val)
{
val = 10;
}
public async Task DoThis(Action act)
{
var t = new Task(act);
t.Start();
await t;
}
As far as I tested it the change was made in the child thread, but still it's effect was visible in the parent thread. Hope this helps You.

You can't do this as you have it (as you know). So, a few work arounds:
You can do this by passing the initial object since it will be a reference type
var a = DoThis(obj);
public async Task DoThis(object obj) //replace the object with the actual object type
{
obj.value = 10;
}
EDIT
Based upon your comments, create an interface and have your classes implement it (providing it's always the same type you want to pass). Then you can pass the interface which is shared (maybe over kill, depends on your needs, or even unrealistic amount of work).
Or, provide a base class with the property! (I don't like this suggestion but since you're asking for something which can't be done it may suffice although I don't recommend it).
An example of the interface is here (not using what you have, but close enough using a Colsone App)
using System;
namespace InterfacesReferenceTypes
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
DoThis(mc);
Console.WriteLine(mc.Number);
Console.ReadKey();
}
static void DoThis(IDemo id)
{
id.Number = 10;
}
}
class MyClass : IDemo
{
//other props and methods etc
public int Number { get; set; }
}
interface IDemo
{
int Number { get; set; }
}
}
EDIT2
After next comments, you will have to still use an interface, but re assign the value afterwards. I'm sure there is a better way to do this, but this works:
using System.Text;
namespace InterfacesRerefenceTypes
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
Console.WriteLine(mc.Number);
mc.val1 = 3;
mc.val2 = 5;
mc.Number = mc.val2;
DoThis(mc);
mc.val2 = mc.Number;
Console.WriteLine(mc.val2);
Console.ReadKey();
}
static void DoThis(IDemo id)
{
id.Number = 15;
}
}
class MyClass : IDemo
{
public int val1 { get; set; }
public int val2 { get; set; }
public int Number { get; set; }
}
interface IDemo
{
int Number { get; set; }
}
}

Related

How to make sure object is properly initialized without constructor?

I would have to create a constructor with great amount of parameters like:
new MyClass(param1, param2, param3, ..., param100);
Is there any way to initialize object like that in a gradual manner, like:
MyClass obj = new MyClass();
obj.Prop1 = val1;
obj.Prop2 = val2;
obj.checkIfInit() //I am not sure how to do that.
How to verify that it is initialized properly if the crazy constructor is not used?
It seems there is a high amount of repetition in your constructor, which is almost always an indicator of bad design. If possible, why not use a collection type, like an array:
new MyClass(paramArray);
Nice and clean.
If you really need that much parameters, you can usually group them together in categories. Make classes for each of them and pass those instances in. It will make use later on much easier too.
As others have pointed out, you should really not have a constructor with so many parameters - although with Dependency Injection for a data model type class, you do often end up with a lot of parameters. In that case, it's usually best to group the parameters into subsets encapsulated into their own classes.
Notwithstanding that advice, you can address the issue with a variant of the "Builder Pattern".
For example, given:
public sealed class MyClass
{
public MyClass(int prop1, string prop2, DateTime prop3)
{
Prop1 = prop1;
Prop2 = prop2;
Prop3 = prop3;
}
public int Prop1 { get; }
public string Prop2 { get; }
public DateTime Prop3 { get; }
}
First note that it has no default constructor and the properties are all read-only, making this class immutable (often a good idea).
(I have omitted parameter checking for brevity.)
Now you can write a helper class to build the object:
public sealed class MyClassBuilder
{
public MyClass Build()
{
if (!_prop1Set || !_prop2Set || !_prop3Set)
throw new InvalidOperationException("Not all properties set.");
return new MyClass(_prop1, _prop2, _prop3);
}
public MyClassBuilder Prop1(int value)
{
_prop1 = value;
_prop1Set = true;
return this;
}
public MyClassBuilder Prop2(string value)
{
_prop2 = value;
_prop2Set = true;
return this;
}
public MyClassBuilder Prop3(DateTime value)
{
_prop3 = value;
_prop3Set = true;
return this;
}
int _prop1;
string _prop2;
DateTime _prop3;
bool _prop1Set;
bool _prop2Set;
bool _prop3Set;
}
Each method for setting a property returns this, to enable fluent use like so:
var builder = new MyClassBuilder();
builder
.Prop1(1)
.Prop2("test")
.Prop3(DateTime.Now);
var myClass = builder.Build(); // Throws if not all properties set.
This gives you a great deal of flexibility for parameter validation and allowing some parameters to be omitted (by providing suitable defaults).
A real-world example of a builder class is Autofac's ContainerBuilder class, usage of which is described here.
Make all paramter to a class or struct , to help you make controctor be clean.
public class InitData
{
Parmter ....
}
new MyClass(InitData data);
Or use paramters
public class MyClass
{
public MyClass(params[] paramters)
{
foreach(p in paramters)
{ ... }
}
}
Possbie do not make a 'crazy controcter' is best soultion I think.
You can override Equals in order to check the default value:
public class MyClass {
public static readonly MyClass DefaultInstance = new MyClass();
public int Val1 { get; set; }
public int Val2 { get; set; }
// Etc...
public MyClass() {
this.Val1 = 10;
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + Val1.GetHashCode();
hash = hash * 23 + Val2.GetHashCode();
return hash;
}
}
public override bool Equals(Object obj) {
if (obj == this)
{
return true;
}
var other = obj as MyClass;
return other?.Val1 == this.Val1 &&
other?.Val2 == this.Val2;
// Etc...
}
}
Then you can just check using:
if (MyClass.DefaultInstance.Equals(instanceToCheck)) {
... // All defaults
}
C# compiler implicitly gives you a default constructor if you are not writing any Constructor for a class.
Now, If you are explicitly giving an Constructor now the C# Compiler will not provide you any Constructor.
i.e you have only One Constructor with you =>MyClass(param1, param2, param3, ..., param100);
Now, You are trying to Create the object without any Parameters.=>MyClass obj = new MyClass();
So, there will be error every time you compile as the Compiler does not find this type of empty overload of the Constructor which one is not taking any value.
To avoid this use an empty constructor explicitly.
Look for the Following example.
Class1 cs = new Class1();
cs.x = "xyz";
cs.y = "zyx";
if(cs!=null)
{
//This checks the Object is created or not i.e Reference is created.
Console.Write("I'm intialized");
}
else
{
Console.WriteLine("I'm not initialized");
}
And the Class for Class1 follows
class Class1
{
public string x;
public string y;
public Class1(string x,string y)
{
this.x = x;
this.y = y;
}
public Class1()
{
}
}
Check it.

Error on static Class

public class Program
{
public static void Main(string[] args)
{
var c = check.myValue("Example 1"); //This is the pattern I've to use, don't want to create an object (Is it possible to use it with static class)
Console.WriteLine(c.result1);
Console.WriteLine(c.result2);
}
}
public static class check
{
public static void myValue(string qr)
{
public string result1 = "My Name" + qr;
public string result1 = "You're" + qr;
}
}
See here Online Example (Code is not working)
Every thing on main function I've to use exactly the same pattern because I'll use it in a lot of different classes and I don't want to create object each and every time by using non-static class.
Please correct me if I'm wrong
There's a lot wrong with the syntax of that code, which #Sergey addresses in his answer.
You appear to want to return an instance of a class from a static method, and that class should contain two properties.
You can do that by creating the actual, nonstatic class containing the properties:
public class Check
{
public string Result1 { get; set; }
public string Result2 { get; set; }
}
Then return a new instance from the static method therein:
public static Check MyValue(string qr)
{
var result = new Check();
result.Result1 = "My Name" + qr;
result.Result2 = "You're" + qr;
return result;
}
However, you're saying in the comments in your code that you don't want to use an object.
In that case it appears you want to use static properties. That's generally not recommendable, but it would look like this:
public static class Check
{
public static string Result1 { get; set; }
public static string Result2 { get; set; }
public static void MyValue(string qr)
{
Result1 = "My Name" + qr;
Result2 = "You're" + qr;
}
}
Then you can read Check.Result1 after calling the method MyValue().
Your code is totally wrong
myValue method returns void. You cannot assign void return value to variable.
You cannot have public modifiers for local variables.
You cannot have local variables with same name in same scope
If you want to return two values from method, then you should return object with two fields - custom class or tuple. You can also use out parameters, but I don't think it's your case
public static class Check
{
public static Tuple<string, string> MyValue(string qr)
{
return Tuple.Create($"My Name {qr}", $"You're {qr}");
}
}
With C# 7 it's a little bit better. You can write this method in one line and provide names for tuple properties
(string MyName, string YourName) MyValue(string qr) => ($"My Name {qr}", $"You're {qr}");
Usage
var result = Check.MyValue("Example 1");
Console.WriteLine(result.Item1); // result.MyName
Console.WriteLine(result.Item2); // result.YourName
You can practice with creating custom class with nicely named properties instead of using tuples.

How to write universal manipulator using generics?

I have interface that defines value and few operations:
public interface IValue<T>
{
T Value { get; }
void InteractionA(IValue<T> target);
void InteractionB(IValue<T> target);
bool Check(IValue<T> target);
}
Then i implement class based on that interface
public class DoubleValue : IValue<double>
{
public double Value { get; private set; }
public bool Check(IValue<double> target)
{
// ...
return false;
}
public void InteractionA(IValue<double> target)
{
// ...
}
public void InteractionB(IValue<double> target)
{
// ...
}
}
Now i want to make universal manipulator that operates on pool of values and uses generics (so i only write it once). Because of the way i want to use this class in the future it cannot be declared static. Moving generic type into methods also doesn't do any good.
The closest i could get is:
public class ValueManipulator<T>
{
public IEnumerable<IValue<T>> Pool { get; private set; }
public ValueManipulator(IEnumerable<IValue<T>> pool)
{
Pool = pool;
}
public void ManipulateA()
{
foreach (int i in Enumerable.Range(0, Pool.Count()))
{
IValue<T> firstValue = Pool.ElementAt(i);
foreach (IValue<T> secondValue in Pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
public void ManipulateB()
{
// ...
}
}
Main problem with this ValueManipulator class is that i need to know T of IValue used in DoubleValue (in this case double). So it looks like this:
static void Main(string[] args)
{
ValueManipulator<double> doubleManipulator = new ValueManipulator<double>();
doubleManipulator.Manipulate(ProvideDoubles());
}
private static IEnumerable<DoubleValue> ProvideDoubles()
{
yield return new DoubleValue();
yield return new DoubleValue();
yield return new DoubleValue();
}
How do i make ValueManipulator so user does not need to know what type was used in value implementation?
Well, if your ValueManipulator<T> has no state, as appears to be your case according to your code snippets, then simply make the methods generic instead of the class, that way you can leverage type inference.
public class ValueManipulator
{
public void Manipulate<T>(IEnumerable<IValue<T>> pool)
{
foreach (int i in Enumerable.Range(0, pool.Count()))
{
IValue<T> firstValue = pool.ElementAt(i);
foreach (IValue<T> secondValue in pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
}
Now you can simply do:
ValueManipulator myManipulator = new ValueManipulator();
myManipulator.Manipulate(ProvideDoubles()); //type inference will figure out T is double
If this is a valid solution then consider making ValueManipulator a static class:
ValueManipulator.Manipulate(ProvideDoubles());
P.D. Please follow advice in commentaries and change ValueType to some other name thats less confusing.
UPDATE After your latest edit to your question, where you clearly state that ValueManipulator<T> does have state, the solution seems to be implementing a static factory class:
public static class ValueManipulator
{
public static ValueManipulator<T> Create<T>(IEnumerable<IValue<T>> pool)
=> new ValueManipulator<T>(pool);
}
public class ValueManipulator<T> { ... }
And again you let type inference do its job:
var doubleManipulator = ValueManipulator.Create(ProvideDoubles());

Why is Visual Studio 2010 telling me "'System.Delegate' does not contain a definition for 'EndInvoke'"?

Why is Visual Studio 2010 telling me "'System.Delegate' does not contain a definition for 'EndInvoke'" when I call job.Delegate.EndInvoke()? How do I fix it? Note that it likes BeginInvoke() just fine, and doesn't complain if I add EndInvoke() immediately after BeginInvoke() (thought hat doesn't accomplish what I want).
I have a little JobTracker class for tracking backup jobs:
public class JobTracker
{
private class Job
{
public Account Account { get; set; }
public IAsyncResult Result { get; set; }
public Delegate Delegate { get; set; }
public bool IsCompleted { get { return result.IsCompleted } }
public string Instance { get { return Account.Instance } }
}
public List<Job> Running = new List<Job>;
public void AddJob(Account a, IAsyncResult result, Delegate del)
{
var j = new Job { Account = a, Result = result, Delegate = del };
Running.Add(j);
}
public void RemoveJob(Job job)
{
Running.Remove(job);
}
public bool IsInstanceRunning(string instance)
{
return (Running.Count(x => x.Instance == instance) > 0);
}
}
These backup jobs will happen asynchronously via BeginInvoke()/EndInvoke(). The calling code (simplified) looks something like this:
public void BackupAccounts(IEnumerable<Account> accounts, int maxconcurrent = 4)
{
// local copy
List<Accounts> myaccounts = accounts.ToList();
var jobs = new JobTracker();
while (myaccounts.Count > 0)
{
// check our running jobs
foreach (var job in jobs.Running)
{
if (job.IsCompleted)
{
// PROBLEM LINE:
job.Delegate.EndInvoke();
jobs.RemoveJob(job);
}
}
// more jobs!
while (jobs.Count < maxconcurrent)
{
int i = 0;
Account account = null;
// choose the next account on a free instance
while (int < accounts.Count)
{
account = accounts[i];
// instance in use?
if (jobs.InstanceIsRunning(account.Instance))
{
i += 1;
continue;
}
else
{
// start the job
accounts.RemoveAt(i);
BackupDelegate del = new BackupDelegate(BackupAccount, account);
IAsyncResult result = del.BeginInvoke();
jobs.AddJob(account, result, del);
}
}
}
// we're all full up, give it some time to work
Thread.Sleep(2000);
}
}
PS - I know this code can be greatly simplified. It's a first, get-it-working iteration -- I just can't figure out why VS doesn't like it.
When you call BeginInvoke, you're calling it on a specific subclass of Delegate. When you call EndInvoke, you're trying to call it on System.Delegate itself, which won't work. Each subclass declares its own Invoke/BeginInvoke/EndInvoke set of methods - which it has to, given that the signatures of the methods varies according to the signature of the exact delegate type you're talking about. If you look at the documentation for System.Delegate you won't find any of those methods there.
It's not really clear what your code is trying to achieve, but if you want to call EndInvoke, you'll need to make Job.Delegate a specific delegate type.
Because EndInvoke doesn't exist on Delegate. Instead you should have your Job class hold a reference to a BackupDelegate.

Call one constructor from another

I have two constructors which feed values to readonly fields.
public class Sample
{
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
_intField = i;
}
public Sample(int theInt) => _intField = theInt;
public int IntProperty => _intField;
private readonly int _intField;
}
One constructor receives the values directly, and the other does some calculation and obtains the values, then sets the fields.
Now here's the catch:
I don't want to duplicate the
setting code. In this case, just one
field is set but of course there may
well be more than one.
To make the fields readonly, I need
to set them from the constructor, so
I can't "extract" the shared code to
a utility function.
I don't know how to call one
constructor from another.
Any ideas?
Like this:
public Sample(string str) : this(int.Parse(str)) { }
If what you want can't be achieved satisfactorily without having the initialization in its own method (e.g. because you want to do too much before the initialization code, or wrap it in a try-finally, or whatever) you can have any or all constructors pass the readonly variables by reference to an initialization routine, which will then be able to manipulate them at will.
public class Sample
{
private readonly int _intField;
public int IntProperty => _intField;
private void setupStuff(ref int intField, int newValue) => intField = newValue;
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
setupStuff(ref _intField,i);
}
public Sample(int theInt) => setupStuff(ref _intField, theInt);
}
Before the body of the constructor, use either:
: base (parameters)
: this (parameters)
Example:
public class People: User
{
public People (int EmpID) : base (EmpID)
{
// Add more statements here.
}
}
I am improving upon supercat's answer. I guess the following can also be done:
class Sample
{
private readonly int _intField;
public int IntProperty
{
get { return _intField; }
}
void setupStuff(ref int intField, int newValue)
{
//Do some stuff here based upon the necessary initialized variables.
intField = newValue;
}
public Sample(string theIntAsString, bool? doStuff = true)
{
//Initialization of some necessary variables.
//==========================================
int i = int.Parse(theIntAsString);
// ................
// .......................
//==========================================
if (!doStuff.HasValue || doStuff.Value == true)
setupStuff(ref _intField,i);
}
public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
{
setupStuff(ref _intField, theInt);
}
}
Here is an example that calls another constructor, then checks on the property it has set.
public SomeClass(int i)
{
I = i;
}
public SomeClass(SomeOtherClass soc)
: this(soc.J)
{
if (I==0)
{
I = DoSomethingHere();
}
}
Yeah, you can call other method before of the call base or this!
public class MyException : Exception
{
public MyException(int number) : base(ConvertToString(number))
{
}
private static string ConvertToString(int number)
{
return number.toString()
}
}
Constructor chaining i.e you can use "Base" for Is a relationship and "This" you can use for same class, when you want call multiple Constructor in single call.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
When you inherit a class from a base class, you can invoke the base class constructor by instantiating the derived class
class sample
{
public int x;
public sample(int value)
{
x = value;
}
}
class der : sample
{
public int a;
public int b;
public der(int value1,int value2) : base(50)
{
a = value1;
b = value2;
}
}
class run
{
public static void Main(string[] args)
{
der obj = new der(10,20);
System.Console.WriteLine(obj.x);
System.Console.WriteLine(obj.a);
System.Console.WriteLine(obj.b);
}
}
Output of the sample program is
50 10 20
You can also use this keyword to invoke a constructor from another constructor
class sample
{
public int x;
public sample(int value)
{
x = value;
}
public sample(sample obj) : this(obj.x)
{
}
}
class run
{
public static void Main(string[] args)
{
sample s = new sample(20);
sample ss = new sample(s);
System.Console.WriteLine(ss.x);
}
}
The output of this sample program is
20
Error handling and making your code reusable is key. I added string to int validation and it is possible to add other types if needed. Solving this problem with a more reusable solution could be this:
public class Sample
{
public Sample(object inputToInt)
{
_intField = objectToInt(inputToInt);
}
public int IntProperty => _intField;
private readonly int _intField;
}
public static int objectToInt(object inputToInt)
{
switch (inputToInt)
{
case int inputInt:
return inputInt;
break;
case string inputString:
if (!int.TryParse(inputString, out int parsedInt))
{
throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
}
return parsedInt;
default:
throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
break;
}
}
Please, please, and pretty please do not try this at home, or work, or anywhere really.
This is a way solve to a very very specific problem, and I hope you will not have that.
I'm posting this since it is technically an answer, and another perspective to look at it.
I repeat, do not use it under any condition. Code is to run with LINQPad.
void Main()
{
(new A(1)).Dump();
(new B(2, -1)).Dump();
var b2 = new B(2, -1);
b2.Increment();
b2.Dump();
}
class A
{
public readonly int I = 0;
public A(int i)
{
I = i;
}
}
class B: A
{
public int J;
public B(int i, int j): base(i)
{
J = j;
}
public B(int i, bool wtf): base(i)
{
}
public void Increment()
{
int i = I + 1;
var t = typeof(B).BaseType;
var ctor = t.GetConstructors().First();
ctor.Invoke(this, new object[] { i });
}
}
Since constructor is a method, you can call it with reflection. Now you either think with portals, or visualize a picture of a can of worms. sorry about this.
In my case, I had a main constructor that used an OracleDataReader as an argument, but I wanted to use different query to create the instance:
I had this code:
public Subscriber(OracleDataReader contractReader)
{
this.contract = Convert.ToString(contractReader["contract"]);
this.customerGroup = Convert.ToString(contractReader["customerGroup"]);
this.subGroup = Convert.ToString(contractReader["customerSubGroup"]);
this.pricingPlan= Convert.ToString(contractReader["pricingPlan"]);
this.items = new Dictionary<string, Member>();
this.status = 0;
}
So I created the following constructor:
public Subscriber(string contract, string customerGroup) : this(getSubReader(contract, customerGroup))
{ }
and this method:
private static OracleDataReader getSubReader(string contract, string customerGroup)
{
cmdSubscriber.Parameters[":contract"].Value = contract + "%";
cmdSubscriber.Parameters[":customerGroup"].Value = customerGroup+ "%";
return cmdSubscriber.ExecuteReader();
}
notes: a statically defined cmdSubscriber is defined elsewhere in the code; My main constructor has been simplified for this illustration.
In case you need to run something before calling another constructor not after.
public class Sample
{
static int preprocess(string theIntAsString)
{
return preprocess(int.Parse(theIntAsString));
}
static int preprocess(int theIntNeedRounding)
{
return theIntNeedRounding/100;
}
public Sample(string theIntAsString)
{
_intField = preprocess(theIntAsString)
}
public Sample(int theIntNeedRounding)
{
_intField = preprocess(theIntNeedRounding)
}
public int IntProperty => _intField;
private readonly int _intField;
}
And ValueTuple can be very helpful if you need to set more than one field.
NOTE: most of the solutions above does not work for structs.
Unfortunately initializing struct fields in a method called by a constructor is not recognized by the compiler and will lead to 2 errors:
in the constructor: Field xxxx must be fully assigned...
in the method, if you have readonly fields: a read-only field cannot be assigned except in a constructor.
These can be really frustrating for example when you just need to do simple check to decide on which constructor to orient your call to.

Categories

Resources