How to identify an anonymous function - c#

I have a class that creates a List<Action<int>> and holds on to them until a later time. This class can add and remove delegates from this list. This works well as long as people don't get too fancy. To combat anonymous function (which can't be removed) I check against the target of the delegate being null. If its null I throw an exception. The problem comes in when there is an anonymous delegate that contains a function. This has a target, but is just as unremovable. The simplified code below illustrates my issues
public class MyDelegateContainer
{
List<Action<int>> m_Container = new List<Action<int>>();
public void Add(Action<int> del)
{
if (del.Target == null)
{
throw new Exception("No static handlers");
}
m_Container.Add(del);
}
public bool Remove(Action<int> del)
{
if (m_Container.Contains(del))
{
m_Container.Remove(del);
return true;
}
return false;
}
}
public class MyFakeActionClass
{
public void Test(int temp) { }
}
class Program
{
static void Main(string[] args)
{
bool removed = false;
int counter = 0;
MyDelegateContainer container = new MyDelegateContainer();
MyFakeActionClass fake = new MyFakeActionClass();
//container.Add(p => { }); //Throws, this is what I want to happen
container.Add(fake.Test); //Works, this is the use case
removed = container.Remove(fake.Test); //Works, this is the use case
Debug.Assert(removed);
container.Add(p => { fake.Test(p); counter++; }); //Works but I would like it not to
removed = container.Remove(p => { fake.Test(p); counter++; }); //doesn't work
Debug.Assert(removed);
}
}
I need some way to identify
p => { fake.Test(p); counter++; }
is an anonymous function so I can throw if someone tries it. Thanks for any help
EDIT: I should note that I could use an Action<int> variable for the anonymous function and everything would work, but the Add and Remove are never in the same scope in practice.

In your example, the caller is responsible from removing the handler. So, if the caller doesn't want to remove the handler, it won't get removed, no matter if the handler is an anonymous delegate/lambda or not.
My suggestion is to change the delegate container to something like this:
public class MyDelegateContainer
{
List<Action<int>> m_Container = new List<Action<int>>();
public Action Add(Action<int> del)
{
m_Container.Add(del);
return new Action(() =>
{
m_Container.Remove(del);
});
}
}
The caller is still responsible for removing the handler, but instead of passing the handler again to the container, it receives a "token" that it can save and use later to remove the handler.

There is no way to reliably determine whether a function is "anonymous" because all functions have names to the CLR. It's only anonymous within the language that generates it, and that's compiler-dependent. You may be able to determine the algorithm used by Microsoft's current C# compiler, only to have it stop working on C# 5 or Mono.
Since you want to prevent users of your type from writing code that uses it wrong, you just need to throw an exception at some point that will make their program crash. What I would do is throw the exception in the Remove function when the target delegate isn't found. At that point your users will still get a crash and the only way to fix it is to write the delegate in some way that it's removable.
As an added bonus, you will catch bugs where somebody tries to remove delegates twice or that were never added in the first place. The code would look like this:
public bool Remove(Action<int> del)
{
if (m_Container.Contains(del))
{
m_Container.Remove(del);
return true;
}
throw new ArgumentException("Attempt to remove nonexistent delegate");
}

I would use introspection to check the names of the methods.
Anonymous methods typically have very predictable names. (I don't remember the exact format, but run some tests, and it should be obvious).
The drawback would be that if anyone created a non-anonymous method, but decided to name it anonMethod123 (or whatever the format is...) It would be falsely rejected.

Of course you can remove an anonymous method, you just need to have a reference to the same anonymous method.
var myAnonymousMethod = p => { fake.Test(p); counter++; };
container.Add(myAnonymousMethod);
removed = container.Remove(myAnonymousMethod);

As jonnii suggested in a comment, another way you could implement it is with a dictionary:
public class MyDelegateContainer
{
Dictionary<string, Action<int>> m_Container =
new Dictionary<string, Action<int>>();
public void Add(string key, Action<int> del)
{
m_Container.Add(key, del);
}
public bool Remove(string key)
{
return m_Container.Remove(key);
}
}
Then you could easily remove a known delegate at some arbitrary point in your code just by knowing what name was used to add it:
container.Add("fake.Test", fake.Test);
removed = container.Remove("fake.Test");
Debug.Assert(removed);
container.Add("anon", p => { fake.Test(p); counter++; });
removed = container.Remove("anon"); // works!
Debug.Assert(removed);

Old question I know but I would think that this would be a current (and future) proofed way of checking if a method is anonymous:
bool isAnonymous = !System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(del.Method.Name);
The runtime name of the anonymous method would have to be invalid if used at compilation time to ensure that it didn't clash.

Related

Getting all results from Func call

The concept of delegates aren't too new to me but I cannot seem to find out how to get all results from a Func delegates. More specifically, I have a class that has a Func delegate that returns a type bool. Something like this...
private Func<Employee, Shift, bool> qualificationCheckCallback;
There are both 'register' and 'unregister' methods for the callback as well. My goal is to see if any of the methods stored in the delegate return false when invoked later in code. Any insight you may have on this issue is much appreciated! Thanks.
You are using the wrong pattern. I'd recommend storing a list of these delegates and iterating over the list, rather than using multidelegates to call multiple targets.
You can make this work (if you need to) by changing the signature to include a "state" variable that is passed by reference to each caller:
private Action<Employee, Shift, QualCheckState> qualificationCheckCallback;
public class QualCheckState { public bool Passed { get; set; } }
// Call it thus:
var state = new QualCheckState { Passed = true }; // Hope for the best
qualificationCheckCallback(someEmployee, someShift, state);
if (state.Passed) {
// Assume everyone passed
}
Keep in mind, this requires the callees to honor the signature, and not overwrite anyone else's failed state:
public void SomeCallee(Employee e, Shift s, State state) {
// If some other check failed, don't bother doing our check.
if (!state.Passed) return;
// Do some check here
if (checkFailed) state.Passed = false;
}
Of course, you can also extend this pattern to make it safer:
public class QualCheckState {
private List<bool> _results = new List<bool>();
public bool Passed { get { return _results.All(s => s); }
public void RecordResult(bool result) {
_results.Add(result);
}
}
As mentioned in Andrew's answer, if you simply invoke qualificationCheckCallback like a normal method, you'll only get back the return value from one of the methods. For this reason, it's pretty unusual to have multicast delegates that have a return value.
If your goal is to see if at least one of the methods stored in your delegate returns false, you'll need to invoke the methods individually. Here is one way to do that using the Delegate.GetInvocationList() method:
bool hasAtLeastOneFalse = false;
if (qualificationCheckCallback != null)
{
foreach(var f in qualificationCheckCallback.GetInvocationList()
.Cast<Func<Employee, Shift, bool>>())
{
if (!f(employee, shift))
{
hasAtLeastOneFalse = true;
// break; // If you don't care about invoking all delegates, you can choose to break here.
}
}
}
Console.WriteLine(hasAtLeastOneFalse);
I'm not suggesting this is a good practice, but it can be done.
A quick search on MSDN found this thread:
https://social.msdn.microsoft.com/Forums/en-US/38a638fe-4a7d-44d6-876c-729d90c20737/how-to-get-return-value-from-delegate?forum=csharplanguage
The problem with events is that the return values cannot be fully
trusted. You will get only one return value no matter how many
subscribers that you have for the event. The central issue is that
you cannot reliably determine which subscriber produced the return
value. The beauty of the .NET Event Model is the anonymity that it
uses. That means event subscribers are completely abstracted from the
event publishers.

Subscribe delegates to all methods of a class

I have just familiarized myself a little bit with C# delegates. One can subscribe multiple delegate instances to a delegate by the "+=" operator. But is it also possible to have a controller class that has delegates for all the methods in second class, and have the methods being added automatically, i.e. without having to add (or even know) each method individually to the corrsponding delegate ?
In simplified code (omitting access modifiers etc.):
class Car
{
void Start();
void Drive();
}
// I would like to have the following class generated automatically
// without needing to repeat all the methods of Car, i.e.
// without declaring a delegate instance for each of them
class CarController
{
delegate void DoSomething();
DoSomething StartAll;
DoSomething DriveAll;
void Subscribe(Car anotherCar)
{
StartAll += anotherCar.Start;
DriveAll += anotherCar.Drive;
}
}
EDIT:
Rawling's solution is the one that I like best. It's simple and clear. As a little tweak I have tried how the thing would work with dynamically typed objects, and it works indeed: complete decoupling between Controller and controlled objects. Of course such usage of "dynamic" is not of everyone's taste...
public class CallAller2 : HashSet<dynamic>
{
public void CallAll(Action<dynamic> action)
{
foreach (dynamic t in this)
{
try {action(t);} catch (RuntimeBinderException) {};
}
}
}
class Bike
{
void Drive();
}
CallAller2 ca = new CallAller2();
ca.Add(new Car());
ca.Add(new Bike());
ca.CallAll(c => c.Start()); // is ignored by Bike which does not implement it
ca.CallAll(c => c.Drive());
Now I realise this is just essentially recreating the much-maligned List<T>.ForEach. Why not just use that, since it's there?
Although it doesn't give you the ability to just call .StartAll or .DriveAll, you could do something as simple as
class CallAller<T> : HashSet<T>
{
public void CallAll(Action<T> action)
{
foreach (T t in this)
{
action(t);
}
}
}
var ca = new CallAller<Car>();
ca.Add(myFirstCar);
ca.Add(mySecondCar);
// Call a simple function
ca.CallAll(c => c.Start());
// Call a function taking parameters
ca.CallAll(c => c.SetRadio(88.1, RadioType.FM));
// Get return values... if you really need to.
Dictionary<Car, int> returnValues = new Dictionary<Car, int>();
ca.CallAll(c => returnValues.Add(c, c.GetNumberOfTyres()));
If you want something with actual methods to call and Intellisense, you'll need to look into code generation - it's possible, but I doubt it'd be worth the hassle.
I think this should work:
//Edit: Don't simplify the MethodInfo mi1 = mi, otherwise you get a problem called Access to modified closure
static IList<Action> getDelegatesFromObject(Object obj)
{
Type type = obj.GetType();
List<Action> Actions = new List<Action>();
foreach (MethodInfo mi in type.GetMethods())
{
MethodInfo mi1 = mi;
Actions.Add(
() => mi1.Invoke(obj, new object[] {})
);
}
return Actions;
}

Can methods be called via an array in C#?

I have a program that will need to run different methods depending on what I want it to talk to, and I want to know if there is a way to store some sort of method pointer or something of that sort in an array. So I want an array where each element would be something like this:
[Boolean: Do_this?] [Function_pointer] [Data to pass to the function]
So basically, I can put this into a for loop and not call each function individually. Another block of code would fill in the Boolean of whether to run this function or not, and then my for loop would go through and run the function with its appropriate data if the Boolean is true.
I know delegates are similar to function pointers, but if that is the answer here, I'm not entirely sure how I would construct what I want to construct.
Is this possible in C#?
Sure is, although, to do it this way, you need all methods to have the same signature:
Lets say you had two methods:
public int Moop(string s){ return 1; }
public int Moop2(string s){ return 2; }
You could do:
var funcs = new Func<string, int>[]{ Moop, Moop2 };
And to call:
var val = funcs[0]("hello");
You could declare a specific object type to hold in a delegate, a flag that indicates whether to do that or now and the data. Note that what you are describing is very similar to events as they are also defined by a callback and some event data.
The skeletal model would look something like this, assuming all methods you want to call have the same signature (you can work around that, if you need a whole bunch of various signatures by using reflection):
// This reflects the signature of the methods you want to call
delegate void theFunction(ActionData data);
class ActionData
{
// put whatever data you would want to pass
// to the functions in this wrapper
}
class Action
{
public Action(theFunction action, ActionData data, bool doIt)
{
this.action = action;
this.data = data;
this.doIt = doIt;
}
public bool doIt
{
get;
set;
}
public ActionData data
{
get;
set;
}
public theFunction action
{
get;
set;
}
public void run()
{
if (doIt)
action(data);
}
}
And a regular use case would look something like this:
class Program
{
static void someMethod(ActionData data)
{
Console.WriteLine("SUP");
}
static void Main(string[] args)
{
Action[] actions = new Action[] {
new Action(Program.someMethod, new ActionData(), true)
};
foreach(Action a in actions)
a.run();
}
}
Yes, you can.
If all your functions share the same signature you might want to store delegates in your collection, otherwise I would go for System.Reflection.MethodInfo, which you can use later on by calling Invoke method. Parameters would be stored as array of objects - that's what Invoke expects.
If using reflection is too slow you can use Reflection.Emit to generate dynamic methods at runtime.
I would just create a List<Action>. Action is a delegate that takes no parameters and returns no results. You can use currying and lambdas such that the actual actions can call a method that has parameters. In the case where you don't actually want to run it, just don't add it to the list in the first place (or add an action that does nothing I guess).
To add an item it might look something like:
list.Add(() => someobject.someMethod(firstArgument, secondArgument));
list.Add(() => anotherObject.anotherMethod(oneArgument));
Then you can just run all of the actions when you want to:
foreach(Action action in list)
{
action();
}
This is exactly what you would use delegates for. Delegates are, more or less, type-checked function pointers. You can create some delegates and put them into an array.
Func<int, int> [] funcs = new Func<int,int>[] { x => 2 * x, x => x * x };
foreach(var fn in funcs)
{
Console.WriteLine(fn(3));
Console.WriteLine(fn(8));
}

How to pass method as a parameter for another method

I need to examine in "parent" object is there an acceptable at a definite moment to call some method in the "child". For example, parent object (component) includes child objects (or component parts in other words) and parent is disposing now, so all (or particlar) child activities must be prohibited (i.e. starting new service threads, enqueueing new client requests, ...).
public class Parent
{
public bool IsMethodCallAcceptable(reference_to_method) {...}
}
public class Child
{
public int SomeMethod(int intArg, string stringArg)
{
if(!_parent.IsMethodCallAcceptable(reference_to_SomeMethod_with_actual_args))
throw new ...
...
}
private void AnotherMethod(string param = null) {...}
{
if(!_parent.IsMethodCallAcceptable(reference_to_AnotherMethod_with_actual_args))
throw new ...
...
}
private Guid ThirdMethod()
{
if(!_parent.IsMethodCallAcceptable(reference_to_ThirdMethod))
throw new ...
...
}
}
Is there any way to do it?
Note: I am answering your question, not your title. Others have answered the title.
Some objects have an isDisposed property, if your parent implements that and that is the only time you don't want to call methods, then yes. Otherwise no. If you control the source for the parent, you could add a property that does what you want.
If you don't control the source and you want to check more than isDisposed or the parent doesn't implement isDisposed, you might be able to check publicly exposed properties, but generally you should assume that if a method is exposed to the public, that it is acceptable to call it at any time. If you're calling private methods via reflection, then you're taking chances.
Edit in response to comment:
Given your description, delegates won't give you any additional capability that you can't do easier by adding properties and methods to the parent (if you don't control the source, they won't help at all). The best method for dealing with your described scenario (CAR.ENGINE.START when out of gas, is for the Start method to either throw an exception or return a value indicationg the result of the attempt to start the engine).
Use delegates?
http://msdn.microsoft.com/en-us/library/ms173171%28v=vs.80%29.aspx
The easiest way is to pass an URI instead of a reference:
"NS.Child.ThirdMethod" for example.
Otherwise, a delegate is what is the closest to a function reference. You can pass that if you want.
However, this method is not compliant with OOP conception rules: Base class should know nothing about its children classes.
It's better to use some kind of locking mechanism to tell the children that they can't have access to the resources.
use func Func<T, TResult>
link
If these methods are native to the child class, the parent can't know anything about them for sure. Rice's Theorem will cause you all kinds of problems, if you could even see the code. Same problem (but to a lesser degree) if they're native to the parent class and are being overridden in the child, since you can't really guarantee that the child class will be doing everything (and only those things) that the parent class does; in fact, you can all but guarantee it will do something different. (If it didn't, why override?)
If they're native to the parent class and not overridable in the child, then just check whether the object is in a valid state for doing such a thing and throw an exception if it isn't.
As far as the actual validity check, for your example you can have a method like bool IsDisposing(); for other cases, you might keep track of the state in some other way. A private method like CanDoThisThing() might help, for example. Having a method that takes a generic operation name (not an operation; we already established the infeasibility of that) seems kinda broken to me.
Thank you all again, the result in the first approach is listed below
public class Component
{
public ComponentPart SomeComponentPart1 { get; private set; }
public ComponentPart SomeComponentPart2 { get; private set; }
public Component()
{
SomeComponentPart1 = new ComponentPart(this);
SomeComponentPart2 = new ComponentPart(this);
}
public bool IsMethodCallAcceptable(MethodCallExpression method, object[] parameters)
{
// collect needed information about caller
var caller = (method.Object as ConstantExpression).Value;
var methodName = method.Method.Name;
var paramsArray = new Dictionary<string, object>();
for (int i = 0; i < method.Arguments.Count; i++)
paramsArray.Add((method.Arguments[i] as MemberExpression).Member.Name, parameters[i]);
// make corresponding decisions
if (caller == SomeComponentPart2)
if (methodName == "SomeMethod")
if ((int) paramsArray["intArg"] == 0 || (string) paramsArray["stringArg"] == "")
return false;
return true;
}
}
public class ComponentPart
{
private Component Owner { get; set; }
public ComponentPart(Component owner)
{
Owner = owner;
}
public int SomeMethod(int intArg, string stringArg)
{
// check if the method call with provided parameters is acceptable
Expression<Func<int, string, int>> expr = (i, s) => SomeMethod(intArg, stringArg);
if (!Owner.IsMethodCallAcceptable(expr.Body as MethodCallExpression, new object[] { intArg, stringArg }))
throw new Exception();
// do some work
return stringArg.Length + intArg;
}
public void AnotherMethod(bool boolArg, Dictionary<Guid, DateTime> crazyArg, string stringArg, object objectArg)
{
// check if the method call with provided parameters is acceptable
Expression<Action<bool, Dictionary<Guid, DateTime>, string, object>> expr =
(b, times, arg3, arg4) => AnotherMethod(boolArg, crazyArg, stringArg, objectArg);
if (!Owner.IsMethodCallAcceptable(expr.Body as MethodCallExpression, new [] { boolArg, crazyArg, stringArg, objectArg }))
throw new Exception();
// do some work
var g = new Guid();
var d = DateTime.UtcNow;
}
}
This is variant how to check method calls, the same approach can be used in order to check properties values changes, while some ComponentPart' methods and properties can check some public Component.State property (via ComponentPart.Owner) instead of calling Component.IsMethodCallAcceptable or Component.IsPropertyChangeAcceptable.

Call/Invoke a method based on a string value contained in an array [duplicate]

This question already has answers here:
Calling a function from a string in C#
(5 answers)
Closed 1 year ago.
I have a struct-array that contains details of different reports that can be run. Each report calls a different method and currently the program has to manually check the selected report value to specifically call the appropriate method.
I would like to store the method name in the struct-array and then have program invoke that method when there is match. Is this possible?
Currently:
if (this.cboSelectReport.Text == "Daily_Unload")
{
reportDailyUnload();
}
Ideally:
if(this.cboSelectReport.Text == MyArray[i].Name)
{
something(MyArray[i].MethodName);
}
UPDATE
I tired a number of the suggestions below and none of them worked. They didn't work probably due to how I have my program structured.
You can do it using reflection, but IMO it is too fragile: it introduces an invisible dependency on the name of the method that you call.
// Assuming that the method is static, you can access it like this:
var namedReportMethod = "MyReport1";
var reportMethod = typeof(ReporterClass).GetMethod(namedReportMethod);
var res = reportMethod.Invoke(null, new object[] {reportArg1, reportArg2});
A better approach would be to define a delegate based on your method, and store it in the struct/class instead of the method name.
delegate void ReportDelegate(int param1, string param2);
class Runner {
public static void RunReport(ReportDelegate rd) {
rd(1, "hello");
}
}
class Test {
static void TestReport(int a, string b) {
// ....
}
public static void Main(string[] args) {
Runner.RunReport(TestReport);
}
}
Instead of defining your own delegate types, you can use pre-defined ones based on Action<T1,T2,...> or Func<T1,T2,R>, depending on your need to return values from the reports.
Rather than storing the method name, you could store a delegate:
struct ReportInfo
{
public string Name { get; set; }
public Action Method { get; set; }
}
//...
MyArray[0] = new ReportInfo { Name = "Daily_Unload", Action = this.reportDailyUnload };
//...
if(this.cboSelectReport.Text == MyArray[i].Name)
{
MyArray[i].Method.Invoke();
}
Most people seem to prefer the alternative syntax where you can invoke a delegate as if it were a method, using a list of arguments in parentheses. I tend to avoid this, because it can be ambiguous whether the thing being invoked is a method or a delegate:
MyArray[i].Method();
In this case, we're invoking the delegate that is referred to by the Method property, but this code could also represent a call to a method called "Method". Confusing.
As for me, supporting simple switch is much easier than dealing with reflection, array of method names or delegates, and invoking that stuff:
switch (reportType)
{
case "Daily_Unload":
ReportDailyUnload();
break;
// ...
}
If all the methods share the same signature, one way would be to cache a delegate:
// initialize, maybe in a constructor
Dictionary<string, Action> nameDelegateMapping = new Dictionary<string, Action>();
// setup the delegates
nameDelegateMapping.Add("Daily_Unload", reportDailyUnload);
// ... add more methods here.
// later
string methodName = this.cboSelectReport.Text;
Action action;
if (nameDelegateMapping.TryGetValue(methodName, out action))
{
action();
}
else
{
// tell user the method does not exist.
}
Yes, what you are talking about is reflection. Here is an article on how to invoke a method. There is a lot you can find on reflection using google.
Add a delegate property to your struct (e.g. of type Action) then just invoke this delegate when you need it. Just set this property to the method you want to call when instantiating the struct instances.
Using a delegate and dictionary<string, delegate>
void Main()
{
var reports = new Dictionary<string, Report>
{
{"Daily_Unload", ReportDailyUnLoad}
};
var report = "Daily_Unload";
reports[report]();
}
delegate string Report();
string ReportDailyUnLoad()
{
return "daily unload report";
}

Categories

Resources