I have something like this. How can i return value form anonymous method?
returnRate = d;. For example let i have some class which get's messages from server. I want to process those messages in classes Cars and Bicycles is that clearly now?
namespace ConsoleApplication9
{
class Program
{
static void Main(string[] args)
{
Cars c = new Cars();
Bicycles b = new Bicycles();
}
}
public class Cars
{
public Cars()
{
GetData G1 = new GetData();
Dictionary<string, string> D1 = new Dictionary<string, string>();
G1.ProcessCars(ref D1);
}
}
public class Bicycles
{
public Bicycles()
{
GetData G2 = new GetData();
Dictionary<string, string> D2 = new Dictionary<string, string>();
G2.ProcessBicycles(ref D2);
}
}
public class Singleton
{
private static Singleton instance;
public Dictionary<string, Action<MessageEventArgs>> Handle;
private Singleton()
{
Handle = new Dictionary<string, Action<MessageEventArgs>>();
}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
public class GetData
{
private Client socket;
public GetData()
{
socket = new Client("http://echo.jsontest.com/bicycles/10");
socket.Message += Message;
}
public void ProcessBicycles(ref Dictionary<string, string> returnRate)
{
Singleton.Instance.Handle.Add("bicycles", (m) =>
{
Dictionary<string, string> d = m.Message.Json.GetFirstArgAs<Dictionary<string, string>>() as Dictionary<string, string>;
//returnRate = d;
});
}
public void ProcessCars(ref Dictionary<string, string> returnRate)
{
Singleton.Instance.Handle.Add("cars", (m) =>
{
Dictionary<string, string> d = m.Message.Json.GetFirstArgAs<Dictionary<string, string>>() as Dictionary<string, string>;
//returnRate = d;
});
}
private void Message(object sender, MessageEventArgs e)
{
if (Singleton.Instance.Handle.ContainsKey(e.Message.Event))
{
Singleton.Instance.Handle[e.Message.Event](e);
}
}
}
}
You'll have to pass in the Action yourself, rather than creating it with a ref parameter. So your Add method simply becomes:
public void Add(Action<string> action) {
Handle.Add("1", action);
}
You can call it like this:
Add(m => ReturnRate = m);
This is a kind of Callback function, which can be used for a kind of asynchronous programming. However, it might be worth your time to read about async and await. If you could give us more information about what your scenario exactly is, we might be able to give you more hints.
If you have to use a ref parameter (for some strange reason), I think you're out of luck...
You should use Func<string,string> instead Action
Action<string> means void function(string s)
Func<string,string> means string function(string s)
However it depends on usage you want to achieve.
This is because the used variables that are used in the the anonymous method body but are outside of it, will be public fields in the generated class made by the compiler. But you can introduce a local variable to make it compilable:
public void Add(ref string rate)
{
string r = rate;
Handle.Add("1", (m) =>
{
Console.WriteLine(m);
r = m;
});
rate = r;
}
And the compiler will generate this in the background:
public void Add(ref string rate)
{
<>c__DisplayClass1 CS$<>8__locals2 = new <>c__DisplayClass1();
CS$<>8__locals2.r = rate;
this.Handle.Add("1", new Action<string>(CS$<>8__locals2.<Add>b__0));
rate = CS$<>8__locals2.r;
}
[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
public string r;
public void <Add>b__0(string m)
{
Console.WriteLine(m);
this.r = m;
}
}
Note: Though this can be compiled, it will not work as you expect, because calling the outer Add will not execute the delegate added by Handle.Add. To return the m from the inner delegate you must use a Func instead.
You should use Func<string,string> (delegate Func<in T,out TResult>) which is equivalent to some function that takes in string and returns string
for eg:-
private string MyFunction(string inputstring){}
Whereas Action<string> (delegate Action<in T>) corresponds to a function which only takes input and returns nothing
private void MyFunction(string inputstring){}
You can modify your code to something like
private Dictionary<string, Func<string,string>> Handle;
private string ReturnRate;
public data()
{
Handle = new Dictionary<string, Func<string,string>>();
Add(ref ReturnRate);
Handle["1"]("MyValue");
Console.WriteLine(ReturnRate);
}
public void Add(ref string rate)
{
string somevalue=rate;
Handle.Add("1", (m) =>
{
Console.WriteLine(m);
somevalue= m;
return m;
});
}
Related
I have a question regarding closures and heap allocation. Consider the following code:
//ORIGINAL CODE, VERSION 1
public class Program
{
private ConcurrentDictionary<object, object> _coll = new ConcurrentDictionary<object, object>();
public object Test(String x){
if(x == "abort") return null;
return _coll.GetOrAdd(x, (k)=> TestCallback());
}
public static object TestCallback() => null;
}
Within Test a static callback function is used. And, according to https://sharplab.io, this gets lowered to (abbr.):
//LOWERED CODE, VERSION 1
public class Program
{
private sealed class <>c
{
public static readonly <>c <>9 = new <>c(); // <== HELPER1 CREATION
public static Func<object, object> <>9__1_0;
internal object <Test>b__1_0(object k)
{
return TestCallback();
}
}
private ConcurrentDictionary<object, object> _coll = new ConcurrentDictionary<object, object>();
public object Test(string x)
{
if (x == "abort")
{
return null;
}
return _coll.GetOrAdd(x, <>c.<>9__1_0 ?? (<>c.<>9__1_0 = new Func<object, object>(<>c.<>9.<Test>b__1_0))); // <== HELPER2 CREATION
}
public static object TestCallback() //==> STATIC METHOD
{
return null;
}
}
So, the compiler creates a few helper objects, but does this only once (the helpers are static).
Now, if I remove static from TestCallback...:
//ORIGINAL CODE, VERSION 1
public class Program
{
private ConcurrentDictionary<object, object> _coll = new ConcurrentDictionary<object, object>();
public object Test(String x){
if(x == "abort") return null;
return _coll.GetOrAdd(x, (k)=> TestCallback());
}
public object TestCallback() => null; //==> INSTANCE METHOD
}
...the lowered code changes to:
//LOWERED CODE, VERSION 2
public class Program
{
private ConcurrentDictionary<object, object> _coll = new ConcurrentDictionary<object, object>();
public object Test(string x)
{
if (x == "abort")
{
return null;
}
return _coll.GetOrAdd(x, new Func<object, object>(<Test>b__1_0)); // <== HELPER1 CREATION
}
public object TestCallback()
{
return null;
}
private object <Test>b__1_0(object k)
{
return TestCallback();
}
}
It now appears that a new Func is created on every call, if x == "abort" is not true (i.e. _coll.GetOrAdd is actually called).
Finally, if I change Test to include a callback parameter...:
//ORIGINAL CODE, VERSION 3
public class Program
{
private ConcurrentDictionary<object, object> _coll = new ConcurrentDictionary<object, object>();
public object Test(String x, Func<object> callback){
if(x == "abort") return null;
return _coll.GetOrAdd(x, (k)=> callback());
}
}
...the lowered code changes to:
//LOWERED CODE, VERSION 3
public class Program
{
private sealed class <>c__DisplayClass1_0
{
public Func<object> callback;
internal object <Test>b__0(object k)
{
return callback();
}
}
private ConcurrentDictionary<object, object> _coll = new ConcurrentDictionary<object, object>();
public object Test(string x, Func<object> callback)
{
<>c__DisplayClass1_0 <>c__DisplayClass1_ = new <>c__DisplayClass1_0(); // <== HELPER1 CREATION
<>c__DisplayClass1_.callback = callback;
if (x == "abort")
{
return null;
}
return _coll.GetOrAdd(x, new Func<object, object>(<>c__DisplayClass1_.<Test>b__0)); // <== HELPER2 CREATION
}
}
Here, it appears as if, a new <>c__DisplayClass1_0 is created on every call, regardless of x == "abort".
To summarize:
Version1: create 2 helpers once.
Version2: create 1 helper whenever _cao..GetOrAdd is actually called.
Version3: create 2 helper on every call.
Is this correct? If the lowered code is correct (and is what the actual compiler uses), why is the creation of new <>c__DisplayClass1_0 not done immediately before the relevant call?
Then unneccessary allocations would be prevented. Ultimately I'm wondering, if this is an actual improvement:
public IMetadata GetOrDefineMetadata(object key, Func<IMetadata> createCallback)
{
if (_coll.TryGetValue(key, out var result)) return result; //THIS LINE WAS INSERTED AS AN IMPROVEMENT
return _coll.GetOrAdd(key, (k) => createCallback()); // ==> WILL THIS STILL CAUSE ALLOCATIONS ON EVERY CALL?
}
This looks like an opportunity for a compiler optimization.
I moved the call to _coll.GetOrAdd to a static method. In the lowered code this moves the allocation further down.
public class Program
{
private ConcurrentDictionary<object, object> _coll = new ConcurrentDictionary<object, object>();
public object Test(String x, Func<object> callback){
if(x == "abort") return null;
return GetOrAdd(x, _coll, callback);
}
private static object GetOrAdd(string x, ConcurrentDictionary<object, object> dict, Func<object> callback)
{
return dict.GetOrAdd(x, (_)=> callback());
}
}
Lowered version:
public class Program
{
[CompilerGenerated]
private sealed class <>c__DisplayClass2_0
{
public Func<object> callback;
internal object <GetOrAdd>b__0(object _)
{
return callback();
}
}
private ConcurrentDictionary<object, object> _coll = new ConcurrentDictionary<object, object>();
public object Test(string x, Func<object> callback)
{
if (x == "abort")
{
return null;
}
return GetOrAdd(x, _coll, callback);
}
private static object GetOrAdd(string x, ConcurrentDictionary<object, object> dict, Func<object> callback)
{
<>c__DisplayClass2_0 <>c__DisplayClass2_ = new <>c__DisplayClass2_0();
<>c__DisplayClass2_.callback = callback;
return dict.GetOrAdd(x, new Func<object, object>(<>c__DisplayClass2_.<GetOrAdd>b__0));
}
}
I am trying to pass a method as an action, but it seems that that the casting is not per say.
This is how I am doing it:
public class RequestHandler<T> where T : struct
{
public enum EmployeeRequests { BasicDetails, DependentsAndEmergencyContacts , MedicalHistory }
protected Dictionary<T, Action> handlers = new Dictionary<T, Action>();
protected EmployeeManagement empMgmnt = new EmployeeManagement();
public void InitializeHandler(int employeeID)
{
this.AddHandler(EmployeeRequests.BasicDetails, () => empMgmnt.GetEmployeeBasicDetails(0));
}
public void AddHandler(T caseValue, Action action)
{
handlers.Add(caseValue, action);
}
public void RemoveHandler(T caseValue)
{
handlers.Remove(caseValue);
}
public void ExecuteHandler(T actualValue)
{
ExecuteHandler(actualValue, Enumerable.Empty<T>());
}
public void ExecuteHandler(T actualValue, IEnumerable<T> ensureExistence)
{
foreach(var val in ensureExistence)
if (!handlers.ContainsKey(val))
throw new InvalidOperationException("The case " + val.ToString() + " is not handled.");
handlers[actualValue]();
}
}
And this is my function that I am passing as a parameter:
public object GetEmployeeBasicDetails(int employeeID)
{
return new { First_Name = "Mark", Middle_Initial = "W.", Last_Name = "Rooney"};
}
I am getting this error:
Overloaded method has some invalid arguments.
UPDATE
This is how I manage to get around this:
public static class RequestHandler
{
public enum EmployeeRequests { BasicDetails = 0, DependentsAndEmergencyContacts = 1 , MedicalHistory = 2 }
private static Dictionary<EmployeeRequests, Func<object>> handlers = new Dictionary<EmployeeRequests, Func<object>>();
public static void InitializeHandler(int employeeID)
{
Func<object> EmpBasicDetails = delegate { return EmployeeManagement.GetEmployeeBasicDetails(0); };
AddHandler(EmployeeRequests.BasicDetails, EmpBasicDetails);
}
private static void AddHandler(EmployeeRequests caseValue, Func<object> empBasicAction)
{
handlers.Add(caseValue, empBasicAction);
}
public static void RemoveHandler(int caseValue)
{
var value = (EmployeeRequests)Enum.Parse(typeof(EmployeeRequests), caseValue.ToString());
handlers.Remove(value);
}
public static object ExecuteHandler(int actualValue)
{
var request = (EmployeeRequests)Enum.Parse(typeof(EmployeeRequests), actualValue.ToString());
return handlers[(EmployeeRequests)request]();
}
}
You cannot pass a value-returning method as an Action, because Action<T> must take a parameter T and return nothing (i.e. void).
You can work around this by passing a lambda that calls your method and ignores its output:
Action empBasicAction = () => GetEmployeeBasicDetails(0);
I have a class that defines a protected field. The protected field has a field initializer.
When I deserialize the concrete class, the field initializer is not run. Why? What is the best pattern to solve the problem? If I move the initialization into a constructor, the constructor is also not invoked.
[DataContract]
public class MyConcrete
{
// FIELD INITIALIZER DOES NOT RUN WHEN COMMENTED IN:
protected readonly Dictionary<int, string> myDict;// = new Dictionary<int, string>();
public MyConcrete()
{
myDict = new Dictionary<int, string>();
}
private bool MyMethod(int key)
{
return myDict.ContainsKey(key);
}
private int myProp;
[DataMember]
public int MyProp
{
get { return myProp; }
set { bool b = MyMethod(value); myProp = value; } // Call MyMethod to provoke error
}
}
ORIGINAL CLASS HIERARCHY
[DataContract]
public abstract class MyAbstract
{
// THIS INITIALIZER IS NOT RUN WHILE DESERIALIZING:
protected readonly Dictionary<int, string> myDict = new Dictionary<int, string>();
private bool MyMethod(int key)
{
return myDict.ContainsKey(key);
}
private int myProp;
[DataMember]
public int MyProp
{
get { return myProp; }
set { bool b = MyMethod(value); myProp = value; } // Call MyMethod to provoke error
}
}
[DataContract]
public class MyConcrete : MyAbstract
{
}
class Program
{
static void Main(string[] args)
{
string tempfn = Path.GetTempFileName();
MyConcrete concrete = new MyConcrete() { MyProp = 42 };
string data = concrete.SerializeToString<MyConcrete>();
MyConcrete rehydrated = SerializationHelper.DeserializeFromString<MyConcrete>(data);
}
}
SUPPORTING METHODS
static public string SerializeToString<T>(this T obj)
{
return SerializationHelper.SerializeToString<T>(obj);
}
static public string SerializeToString<T>(T obj)
{
DataContractSerializer s = new DataContractSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
s.WriteObject(ms, obj);
ms.Position = 0;
using (StreamReader sr = new StreamReader(ms))
{
string serialized = sr.ReadToEnd();
return serialized;
}
}
}
static public T DeserializeFromString<T>(string serializedDataAsString)
{
DataContractSerializer s = new DataContractSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serializedDataAsString)))
{
object s2 = s.ReadObject(ms);
return (T)s2;
}
}
On deserialization neither the constructors nor the field initializers are called and a "blank" un-initialized object is used instead.
To resolve it you can make use of the OnDeserializing or OnDerserialized attributes to have the deserializer call a function with the following signature:
void OnDeserializing(System.Runtime.Serialization.StreamingContext c);
In that function is where you can initialize whatever was missed within the deserialization process.
In terms of convention, I tend to have my constructor call a method OnCreated() and then also have deserializating method call the same thing. You can then handle all of the field initialization in there and be sure it's fired before deserialization.
[DataContract]
public abstract class MyAbstract
{
protected Dictionary<int, string> myDict;
protected MyAbstract()
{
OnCreated();
}
private void OnCreated()
{
myDict = new Dictionary<int, string>();
}
[OnDeserializing]
private void OnDeserializing(StreamingContext c)
{
OnCreated();
}
private bool MyMethod(int key)
{
return myDict.ContainsKey(key);
}
private int myProp;
[DataMember]
public int MyProp
{
get { return myProp; }
set { bool b = MyMethod(value); myProp = value; }
}
}
Another approach is to access your field through a protected (in your example) property, and initialise the field using the null-coalescing (??) operator
protected Dictionary<int, string> myDict = new Dictionary<int, string>();
protected Dictionary<int, string> MyDict
{
get
{
return myDict ?? (myDict = new Dictionary<int, string>());
}
}
The downsides are that you lose the benefits of readonly, and need to make sure that you only access the value via the property.
Is there any way to override a class method with a lambda function?
For example with a class definition of
class MyClass {
public virtual void MyMethod(int x) {
throw new NotImplementedException();
}
}
Is there anyway to do:
MyClass myObj = new MyClass();
myObj.MyMethod = (x) => { Console.WriteLine(x); };
Chris is right that methods cannot be used like variables. However, you could do something like this:
class MyClass {
public Action<int> MyAction = x => { throw new NotImplementedException() };
}
To allow the action to be overridden:
MyClass myObj = new MyClass();
myObj.MyAction = (x) => { Console.WriteLine(x); };
No. However if you declare the method as a lambda in the first place, you can set it, though I would try to do that at initialization time.
class MyClass {
public MyClass(Action<int> myMethod)
{
this.MyMethod = myMethod ?? x => { };
}
public readonly Action<int> MyMethod;
}
This however cannot implement an interface that has a MyMethod declared, unless the interface specifies a lambda property.
F# has object expressions, which allow you to compose an object out of lambdas. I hope at some point this is part of c#.
No. Methods cannot be used like variables.
If you were using JavaScript, then yes, you could do that.
You can write this code:
MyClass myObj = new MyClass();
myObj.TheAction = x => Console.WriteLine(x);
myObj.DoAction(3);
If you define MyClass in this way:
class MyClass
{
public Action<int> TheAction {get;set;}
public void DoAction(int x)
{
if (TheAction != null)
{
TheAction(x);
}
}
}
But that shouldn't be too surprising.
Not directly, but with a little code it's doable.
public class MyBase
{
public virtual int Convert(string s)
{
return System.Convert.ToInt32(s);
}
}
public class Derived : MyBase
{
public Func<string, int> ConvertFunc { get; set; }
public override int Convert(string s)
{
if (ConvertFunc != null)
return ConvertFunc(s);
return base.Convert(s);
}
}
then you could have code
Derived d = new Derived();
int resultBase = d.Convert("1234");
d.ConvertFunc = (o) => { return -1 * Convert.ToInt32(o); };
int resultCustom = d.Convert("1234");
Depending on what you want to do, there are many ways to solve this problem.
A good starting point is to make a delegate (e.g. Action) property that is gettable and settable. You can then have a method which delegates to that action property, or simply call it directly in client code. This opens up a lot of other options, such as making the action property private settable (perhaps providing a constructor to set it), etc.
E.g.
class Program
{
static void Main(string[] args)
{
Foo myfoo = new Foo();
myfoo.MethodCall();
myfoo.DelegateAction = () => Console.WriteLine("Do something.");
myfoo.MethodCall();
myfoo.DelegateAction();
}
}
public class Foo
{
public void MethodCall()
{
if (this.DelegateAction != null)
{
this.DelegateAction();
}
}
public Action DelegateAction { get; set; }
}
I made the example below which enables a factory to pack objects with functionality, but the problem is that the functionality is divorced from the object.
My ultimate goal is attach functionality such as log, and save and display which operates on the specific properties that each different object has.
How would I keep the exterior adorning aspect of this example but enable functionality such as "save" which saves the object's data to a database or "log" which logs its activity?
using System;
using System.Collections.Generic;
namespace FuncAdorn3923
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
ObjectFactory.Instance.AdornFunctionality(customer, "add");
Console.WriteLine(customer.CallAlgorithm("add", 64, 36));
Employee employee = new Employee();
ObjectFactory.Instance.AdornFunctionality(employee, "add");
ObjectFactory.Instance.AdornFunctionality(employee, "subtract");
Console.WriteLine(employee.CallAlgorithm("add", 5, 15));
Console.WriteLine(employee.CallAlgorithm("subtract", 66, 16));
Console.ReadLine();
}
}
public class ObjectFactory
{
private static ObjectFactory singleton;
public void AdornFunctionality(AdornedObject ao, string idCode)
{
Func<int, int, int> add = (i, j) => i + j;
Func<int, int, int> subtract = (i, j) => i - j;
switch (idCode)
{
case "add":
ao.LoadAlgorithm(idCode, add);
break;
case "subtract":
ao.LoadAlgorithm(idCode, subtract);
break;
}
}
public static ObjectFactory Instance
{
get
{
if (singleton == null)
singleton = new ObjectFactory();
return singleton;
}
}
}
public abstract class AdornedObject
{
private Dictionary<string, Func<int, int, int>> algorithms =
new Dictionary<string, Func<int, int, int>>();
public void LoadAlgorithm(string idCode, Func<int,int,int> func)
{
algorithms.Add(idCode, func);
}
public int CallAlgorithm(string idCode, int i1, int i2)
{
Func<int,int,int> func = algorithms[idCode];
return func.Invoke(i1, i2);
}
}
public class Customer : AdornedObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int NumberOfProductsBought { get; set; }
}
public class Employee : AdornedObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
}
I would personally recommend a better design pattern, like the visitor pattern, but for what its worth you can make your code work by throwing away type safety. Use Delegate rather than its derived classes Func and Action:
static void Main(string[] args)
{
Customer customer = new Customer();
ObjectFactory.Instance.AdornFunctionality(customer, "add");
Console.WriteLine(customer.CallAlgorithm("add", 64, 36));
Employee employee = new Employee();
ObjectFactory.Instance.AdornFunctionality(employee, "add");
ObjectFactory.Instance.AdornFunctionality(employee, "subtract");
ObjectFactory.Instance.AdornFunctionality(employee, "save");
Console.WriteLine(employee.CallAlgorithm("add", 5, 15));
Console.WriteLine(employee.CallAlgorithm("subtract", 66, 16));
Console.WriteLine(employee.CallAlgorithm("save"));
Console.ReadLine();
}
}
public class ObjectFactory
{
private static ObjectFactory singleton;
public void AdornFunctionality(AdornedObject ao, string idCode)
{
Func<int, int, int> add = (i, j) => i + j;
Func<int, int, int> subtract = (i, j) => i - j;
Action save = () => Console.WriteLine("{0} has been saved", ao.ToString());
switch (idCode)
{
case "add":
ao.LoadAlgorithm(idCode, add);
break;
case "subtract":
ao.LoadAlgorithm(idCode, subtract);
break;
case "save":
ao.LoadAlgorithm(idCode, save);
break;
}
}
public static ObjectFactory Instance
{
get
{
if (singleton == null)
singleton = new ObjectFactory();
return singleton;
}
}
}
public abstract class AdornedObject
{
private Dictionary<string, Delegate> algorithms = new Dictionary<string, Delegate>();
public void LoadAlgorithm(string idCode, Delegate func)
{
algorithms.Add(idCode, func);
}
public object CallAlgorithm(string idCode, params object[] args)
{
Delegate func = algorithms[idCode];
return func.DynamicInvoke(args);
}
}
This looks like a classic case for the visitor pattern.
The algorithms (visitors) will need to be tailored to the objects they adorn (or visit), or at least tailored to some interface that your adorned objects implement.
For example, your Employee object might have a method like the following:
public class Employee: IEmployee {
public void Accept(IEmployeeAlgorithm algorithm) {
algorithm.Visit(this);
}
}
IEmployeeAlgorithm objects would have an interface similar to this (these could just as easily be Action<Employee> delegates, or use other signatures as needed):
public interface IEmployeeAlgorithm {
void Visit(IEmployee employee);
}
Finally, if you want to give the algorithms keys and invoke them dynamically, you could do that in a fashion similar to what you've got now by storing them in an IDictionary<string, IEmployeeAlgorithm> member.
I would check out the PostSharp project. They allow this kind of separation of concerns and enable some easy ways to accomplish this. They allow you to externally define code which is added to classes/properties at run time. I'm not sure about your specific requirements (or this particular example) but you should check it out.