Is it possible to send an Object's Method to a Function? - c#

I am wondering if it is possible (and what the syntax would be) to send an object's method to a function.
Example:
Object "myObject" has two methods "method1" and "method2"
I would like to have a function along the lines of:
public bool myFunc(var methodOnObject)
{
[code here]
var returnVal = [run methodOnObject here]
[code here]
return returnVal;
}
So that in another function I could do something like
public void overallFunction()
{
var myObject = new ObjectItem();
var method1Success = myFunc(myObject.method1);
var method2Success = myFunc(myObject.method2);
}

Yes, you need to use a delegate. Delegates are fairly analogous to function pointers in C/C++.
You'll first need to declare the signature of the delegate. Say I have this function:
private int DoSomething(string data)
{
return -1;
}
The delegate declaration would be...
public delegate int MyDelegate(string data);
You could then declare myFunc in this way..
public bool myFunc(MyDelegate methodOnObject)
{
[code here]
int returnValue = methodOnObject("foo");
[code here]
return returnValue;
}
You can then call it in one of two ways:
myFunc(new MyDelegate(DoSomething));
Or, in C# 3.0 and later, you can use the shorthand of...
myFunc(DoSomething);
(It just wraps the provided function in the default constructor for that delegate automatically. The calls are functionally identical).
If you don't care to actually create a delegate or actual function implementation for simple expressions, the following will work in C# 3.0 as well:
public bool myFunc(Func<string, int> expr)
{
[code here]
int returnValue = methodOnObject("foo");
[code here]
return returnValue;
}
Which could then be called like so:
myFunc(s => return -1);

Is there really a need for explicit delegates? Maybe this approach would help you:
private class MyObject
{
public bool Method1() { return true; } // Your own logic here
public bool Method2() { return false; } // Your own logic here
}
private static bool MyFunction(Func<bool> methodOnObject)
{
bool returnValue = methodOnObject();
return returnValue;
}
private static void OverallFunction()
{
MyObject myObject = new MyObject();
bool method1Success = MyFunction(myObject.Method1);
bool method2Success = MyFunction(myObject.Method2);
}

Yes, using delegates ..
Here is an example..
delegate string myDel(int s);
public class Program
{
static string Func(myDel f)
{
return f(2);
}
public static void Main()
{
Test obj = new Test();
myDel d = obj.func;
Console.WriteLine(Func(d));
}
}
class Test
{
public string func(int s)
{
return s.ToString();
}
}

Related

Invoke generic delegate [duplicate]

How do I create a Dictionary where I can store functions?
Thanks.
I have about 30+ functions which can be executed from the user. I want to be able to execute the function this way:
private void functionName(arg1, arg2, arg3)
{
// code
}
dictionaryName.add("doSomething", functionName);
private void interceptCommand(string command)
{
foreach ( var cmd in dictionaryName )
{
if ( cmd.Key.Equals(command) )
{
cmd.Value.Invoke();
}
}
}
However, the function signature is not always the same, thus having different amount of arguments.
Like this:
Dictionary<int, Func<string, bool>>
This allows you to store functions that take a string parameter and return boolean.
dico[5] = foo => foo == "Bar";
Or if the function is not anonymous:
dico[5] = Foo;
where Foo is defined like this:
public bool Foo(string bar)
{
...
}
UPDATE:
After seeing your update it seems that you don't know in advance the signature of the function you would like to invoke. In .NET in order to invoke a function you need to pass all the arguments and if you don't know what the arguments are going to be the only way to achieve this is through reflection.
And here's another alternative:
class Program
{
static void Main()
{
// store
var dico = new Dictionary<int, Delegate>();
dico[1] = new Func<int, int, int>(Func1);
dico[2] = new Func<int, int, int, int>(Func2);
// and later invoke
var res = dico[1].DynamicInvoke(1, 2);
Console.WriteLine(res);
var res2 = dico[2].DynamicInvoke(1, 2, 3);
Console.WriteLine(res2);
}
public static int Func1(int arg1, int arg2)
{
return arg1 + arg2;
}
public static int Func2(int arg1, int arg2, int arg3)
{
return arg1 + arg2 + arg3;
}
}
With this approach you still need to know the number and type of parameters that need to be passed to each function at the corresponding index of the dictionary or you will get runtime error. And if your functions doesn't have return values use System.Action<> instead of System.Func<>.
However, the function signature is not
always the same, thus having different
amount of arguments.
Let's start with a few functions defined like this:
private object Function1() { return null; }
private object Function2(object arg1) { return null; }
private object Function3(object arg1, object arg3) { return null; }
You really have 2 viable options at your disposal:
1) Maintain type-safety by having clients call your function directly.
This is probably the best solution, unless you have very good reasons for breaking from this model.
When you talk about wanting to intercept function calls, it sounds to me like you're trying to re-invent virtual functions. There's a boat load of ways to get this sort of functionality out of the box, such as inheriting from a base class an overriding its functions.
It sounds to me like you want a class that's more of a wrapper than a derived instance of a base class, so do something like this:
public interface IMyObject
{
object Function1();
object Function2(object arg1);
object Function3(object arg1, object arg2);
}
class MyObject : IMyObject
{
public object Function1() { return null; }
public object Function2(object arg1) { return null; }
public object Function3(object arg1, object arg2) { return null; }
}
class MyObjectInterceptor : IMyObject
{
readonly IMyObject MyObject;
public MyObjectInterceptor()
: this(new MyObject())
{
}
public MyObjectInterceptor(IMyObject myObject)
{
MyObject = myObject;
}
public object Function1()
{
Console.WriteLine("Intercepted Function1");
return MyObject.Function1();
}
public object Function2(object arg1)
{
Console.WriteLine("Intercepted Function2");
return MyObject.Function2(arg1);
}
public object Function3(object arg1, object arg2)
{
Console.WriteLine("Intercepted Function3");
return MyObject.Function3(arg1, arg2);
}
}
2) OR map the input of your functions to a common interface.
This might work if all of your functions are related. For example, if you're writing a game, and all the functions do something to some part of the player or player's inventory. You'd end up with something like this:
class Interceptor
{
private object function1() { return null; }
private object function2(object arg1) { return null; }
private object function3(object arg1, object arg3) { return null; }
Dictionary<string, Func<State, object>> functions;
public Interceptor()
{
functions = new Dictionary<string, Func<State, object>>();
functions.Add("function1", state => function1());
functions.Add("function2", state => function2(state.arg1, state.arg2));
functions.Add("function3", state => function3(state.arg1, state.are2, state.arg3));
}
public object Invoke(string key, object state)
{
Func<object, object> func = functions[key];
return func(state);
}
}
Define the dictionary and add the function reference as the value, using System.Action as the type:
using System.Collections;
using System.Collections.Generic;
public class Actions {
public Dictionary<string, System.Action> myActions = new Dictionary<string, System.Action>();
public Actions() {
myActions ["myKey"] = TheFunction;
}
public void TheFunction() {
// your logic here
}
}
Then invoke it with:
Actions.myActions["myKey"]();
Hey, I hope this helps. What language are you coming from?
internal class ForExample
{
void DoItLikeThis()
{
var provider = new StringMethodProvider();
provider.Register("doSomethingAndGetGuid", args => DoSomeActionWithStringToGetGuid((string)args[0]));
provider.Register("thenUseItForSomething", args => DoSomeActionWithAGuid((Guid)args[0],(bool)args[1]));
Guid guid = provider.Intercept<Guid>("doSomethingAndGetGuid", "I don't matter except if I am null");
bool isEmpty = guid == default(Guid);
provider.Intercept("thenUseItForSomething", guid, isEmpty);
}
private void DoSomeActionWithAGuid(Guid id, bool isEmpty)
{
// code
}
private Guid DoSomeActionWithStringToGetGuid(string arg1)
{
if(arg1 == null)
{
return default(Guid);
}
return Guid.NewGuid();
}
}
public class StringMethodProvider
{
private readonly Dictionary<string, Func<object[], object>> _dictionary = new Dictionary<string, Func<object[], object>>();
public void Register<T>(string command, Func<object[],T> function)
{
_dictionary.Add(command, args => function(args));
}
public void Register(string command, Action<object[]> function)
{
_dictionary.Add(command, args =>
{
function.Invoke(args);
return null;
} );
}
public T Intercept<T>(string command, params object[] args)
{
return (T)_dictionary[command].Invoke(args);
}
public void Intercept(string command, params object[] args)
{
_dictionary[command].Invoke(args);
}
}
The following scenario would allow you to use a dictionary of elements to send in as input parameters and get the same as the output parameters.
First add the following line at the top:
using TFunc = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Collections.Generic.IDictionary<string, object>>;
Then inside your class, define the dictionary as follows:
private Dictionary<String, TFunc> actions = new Dictionary<String, TFunc>(){
{"getmultipledata", (input) =>
{
//DO WORKING HERE
return null;
}
},
{"runproc", (input) =>
{
//DO WORKING HERE
return null;
}
}
};
This would allow you to run these anonymous functions with a syntax similar to this:
var output = actions["runproc"](inputparam);
Why not use params object[] list for method parameters and do some validation inside either your methods (or calling logic), It will allow for a variable number of parameters.

"No Operation" Delegate in c#

I've a generic class like
public class Foo<T> where T : Delegate {
private T nop;
public Foo(T nop) {
this.nop = nop;
}
public T BuildDelegateChain() {
if(chainAvailable) {
return Delegate.Combine(...) as T;
} else {
return nop;
}
}
....
}
So for each instance I have to call:
Foo<Action<int>> foo = new Foo<Action<int>>( _ =>{});
Foo<Action<int,int>> foo = new Foo<Action<int,int>>( (_,__) =>{});
Is there a way to get a default "No Operation" delegate matching the type T?
I'm looking for something to replace the constructor to a constructor without any argument. Something like:
...
public Foo() {
this.nop = Delegate.CreateNop(typeof(T));
}
...
You can create a no-op delegate dynamically using the Expression class. For delegates with return types, the no-op would have to return default(TReturn). Otherwise it just needs to be an empty block. We'll then cache the delegate so reflection only happens once.
using System.Linq;
using System.Linq.Expressions;
public static class DelegateHelper<T> where T : Delegate
{
public static T NoOp { get; } = BuildNoOpDelegate();
private static T BuildNoOpDelegate()
{
var invoke = typeof(T).GetMethod(nameof(Action.Invoke));
var paramTypes = invoke.GetParameters().Select(c => c.ParameterType);
// return default(TReturn) or default(Void)
var body = Expression.Default(invoke.ReturnType);
var lambda = Expression.Lambda<T>(
body,
paramTypes.Select(Expression.Parameter)
);
return lambda.Compile();
}
}
And then to use it:
public class Foo<T> where T : Delegate {
private T nop;
public Foo() {
nop = DelegateHelper<T>.NoOp;
}
}
Interestingly, this also works for delegates with out/ref parameters. In the case of out we don't need to do anything special to set the values before the method exits (which would be required with straight C#)--they keep their default values. For example, suppose a delegate with the following signature:
public delegate int MyDelegate(out int x, ref string y);
This code will compile and execute successfully:
var nop = DelegateHelper<MyDelegate>.NoOp;
string val = "hello";
int ret = nop(out int i, ref val);
Console.WriteLine(ret); // prints "0"
Console.WriteLine(i); // prints "0"
Console.WriteLine(val); // unchanged, prints "hello"
Now this is all probably a bit overkill, but it should answer your question. Alternatively you could just treat null as your no-op sentinel value and use whatever?.Invoke() instead.

Overloading generic interface parameters in C#

I have created the following class:
class GenericTest
{
public T Do<T>( T test ) where T : class
{
return test;
}
public IEnumerable<T> Do<T>( List<T> test ) where T : class
{
return test;
}
public IEnumerable<T> Do<T>( IEnumerable<T> test ) where T : class
{
return test;
}
}
This has three overloads of the Do() function. I'm trying to understand how the method parameter matching works in C# for generics, especially around interface parameters. So, I have the following test program:
static void Main( string[] args )
{
GenericTest testing = new GenericTest();
string s = "TEST";
List<string> list = new List<string> {s};
Stack<string> stack = new Stack<string>();
stack.Push( s );
testing.Do( s ); //calls public T Do<T>( T test )
testing.Do( list ); //calls IEnumerable<T> Do<T>( List<T> test )
testing.Do( stack ); //calls public T Do<T>( T test ) where T : class
}
The first call to Do() works as I expected, then the concrete class List parameter matches nicely against the List parameter method, but when I pass an IEnumerable, the compiler doesn't use the IEnumerable parameter method, instead it chooses the generic T method. Is this expected behaviour? Can I not overload with just an interface parameter in a generic?
I'm not sure if first call works as expected since string is IEnumerable<char> ...
Which method should be executed in such case? It depends on your particular requirement.
Behaviour that you are describing may be flexibly implemented following CoR pattern where you define matching logic and chain elements order according your particular needs.
Below is just an illustration that shows the idea(I'm sure it can be refactored):
public abstract class ChainElem
{
public abstract bool IsMatching(object o);
public abstract void Do(object o);
}
public class ChainElemIList : ChainElem{
public override bool IsMatching(object o) {
//Matches IList implementations only.
if( o is IList )
return true;
else
return false;
}
public override void Do(object o) {
//Do something with the IList
Console.WriteLine("processing IList...");
}
}
public class ChainElemIEnumerable : ChainElem{
public override bool IsMatching(object o) {
//Matches all IEnumerable implementations(but not string).
//This is something that you won't achieve with generics.
if( o is IEnumerable && !(o is string) )
return true;
else
return false;
}
public override void Do(object o) {
//Do something with the IEnumerable(but not string)
Console.WriteLine("processing IEnumerable(but not string)...");
}
}
public class ChainElemString : ChainElem{
public override bool IsMatching(object o) {
//Matches strings only.
if( o is string )
return true;
else
return false;
}
public override void Do(object o) {
//Do something with the string
Console.WriteLine("processing string...");
}
}
public class ChainElemObject : ChainElem{
public override bool IsMatching(object o) {
//Matches everything else.
return true;
}
public override void Do(object o) {
//Do something with the object
Console.WriteLine("processing object...");
}
}
void Main()
{
string s = "TEST";
List<string> list = new List<string> {s};
Stack<string> stack = new Stack<string>();
stack.Push( s );
object o = new object();
//construct the chain - order is important and depends on your requirements
var chain = new List<ChainElem> {
new ChainElemIList(),
new ChainElemIEnumerable(),
new ChainElemString(),
new ChainElemObject()
};
//processing
chain.First(c => c.IsMatching(list)).Do(list);
chain.First(c => c.IsMatching(stack)).Do(stack);
chain.First(c => c.IsMatching(s)).Do(s);
chain.First(c => c.IsMatching(o)).Do(o);
//OUTPUT:
// processing IList...
// processing IEnumerable(but not string)...
// processing string...
// processing object...
}
So, it seems that you can't overload with a interface parameter if you have generic method that matches the signature.
Either use a different name for your methods, or a concrete class in the parameter list.

C# Store functions in a Dictionary

How do I create a Dictionary where I can store functions?
Thanks.
I have about 30+ functions which can be executed from the user. I want to be able to execute the function this way:
private void functionName(arg1, arg2, arg3)
{
// code
}
dictionaryName.add("doSomething", functionName);
private void interceptCommand(string command)
{
foreach ( var cmd in dictionaryName )
{
if ( cmd.Key.Equals(command) )
{
cmd.Value.Invoke();
}
}
}
However, the function signature is not always the same, thus having different amount of arguments.
Like this:
Dictionary<int, Func<string, bool>>
This allows you to store functions that take a string parameter and return boolean.
dico[5] = foo => foo == "Bar";
Or if the function is not anonymous:
dico[5] = Foo;
where Foo is defined like this:
public bool Foo(string bar)
{
...
}
UPDATE:
After seeing your update it seems that you don't know in advance the signature of the function you would like to invoke. In .NET in order to invoke a function you need to pass all the arguments and if you don't know what the arguments are going to be the only way to achieve this is through reflection.
And here's another alternative:
class Program
{
static void Main()
{
// store
var dico = new Dictionary<int, Delegate>();
dico[1] = new Func<int, int, int>(Func1);
dico[2] = new Func<int, int, int, int>(Func2);
// and later invoke
var res = dico[1].DynamicInvoke(1, 2);
Console.WriteLine(res);
var res2 = dico[2].DynamicInvoke(1, 2, 3);
Console.WriteLine(res2);
}
public static int Func1(int arg1, int arg2)
{
return arg1 + arg2;
}
public static int Func2(int arg1, int arg2, int arg3)
{
return arg1 + arg2 + arg3;
}
}
With this approach you still need to know the number and type of parameters that need to be passed to each function at the corresponding index of the dictionary or you will get runtime error. And if your functions doesn't have return values use System.Action<> instead of System.Func<>.
However, the function signature is not
always the same, thus having different
amount of arguments.
Let's start with a few functions defined like this:
private object Function1() { return null; }
private object Function2(object arg1) { return null; }
private object Function3(object arg1, object arg3) { return null; }
You really have 2 viable options at your disposal:
1) Maintain type-safety by having clients call your function directly.
This is probably the best solution, unless you have very good reasons for breaking from this model.
When you talk about wanting to intercept function calls, it sounds to me like you're trying to re-invent virtual functions. There's a boat load of ways to get this sort of functionality out of the box, such as inheriting from a base class an overriding its functions.
It sounds to me like you want a class that's more of a wrapper than a derived instance of a base class, so do something like this:
public interface IMyObject
{
object Function1();
object Function2(object arg1);
object Function3(object arg1, object arg2);
}
class MyObject : IMyObject
{
public object Function1() { return null; }
public object Function2(object arg1) { return null; }
public object Function3(object arg1, object arg2) { return null; }
}
class MyObjectInterceptor : IMyObject
{
readonly IMyObject MyObject;
public MyObjectInterceptor()
: this(new MyObject())
{
}
public MyObjectInterceptor(IMyObject myObject)
{
MyObject = myObject;
}
public object Function1()
{
Console.WriteLine("Intercepted Function1");
return MyObject.Function1();
}
public object Function2(object arg1)
{
Console.WriteLine("Intercepted Function2");
return MyObject.Function2(arg1);
}
public object Function3(object arg1, object arg2)
{
Console.WriteLine("Intercepted Function3");
return MyObject.Function3(arg1, arg2);
}
}
2) OR map the input of your functions to a common interface.
This might work if all of your functions are related. For example, if you're writing a game, and all the functions do something to some part of the player or player's inventory. You'd end up with something like this:
class Interceptor
{
private object function1() { return null; }
private object function2(object arg1) { return null; }
private object function3(object arg1, object arg3) { return null; }
Dictionary<string, Func<State, object>> functions;
public Interceptor()
{
functions = new Dictionary<string, Func<State, object>>();
functions.Add("function1", state => function1());
functions.Add("function2", state => function2(state.arg1, state.arg2));
functions.Add("function3", state => function3(state.arg1, state.are2, state.arg3));
}
public object Invoke(string key, object state)
{
Func<object, object> func = functions[key];
return func(state);
}
}
Define the dictionary and add the function reference as the value, using System.Action as the type:
using System.Collections;
using System.Collections.Generic;
public class Actions {
public Dictionary<string, System.Action> myActions = new Dictionary<string, System.Action>();
public Actions() {
myActions ["myKey"] = TheFunction;
}
public void TheFunction() {
// your logic here
}
}
Then invoke it with:
Actions.myActions["myKey"]();
Hey, I hope this helps. What language are you coming from?
internal class ForExample
{
void DoItLikeThis()
{
var provider = new StringMethodProvider();
provider.Register("doSomethingAndGetGuid", args => DoSomeActionWithStringToGetGuid((string)args[0]));
provider.Register("thenUseItForSomething", args => DoSomeActionWithAGuid((Guid)args[0],(bool)args[1]));
Guid guid = provider.Intercept<Guid>("doSomethingAndGetGuid", "I don't matter except if I am null");
bool isEmpty = guid == default(Guid);
provider.Intercept("thenUseItForSomething", guid, isEmpty);
}
private void DoSomeActionWithAGuid(Guid id, bool isEmpty)
{
// code
}
private Guid DoSomeActionWithStringToGetGuid(string arg1)
{
if(arg1 == null)
{
return default(Guid);
}
return Guid.NewGuid();
}
}
public class StringMethodProvider
{
private readonly Dictionary<string, Func<object[], object>> _dictionary = new Dictionary<string, Func<object[], object>>();
public void Register<T>(string command, Func<object[],T> function)
{
_dictionary.Add(command, args => function(args));
}
public void Register(string command, Action<object[]> function)
{
_dictionary.Add(command, args =>
{
function.Invoke(args);
return null;
} );
}
public T Intercept<T>(string command, params object[] args)
{
return (T)_dictionary[command].Invoke(args);
}
public void Intercept(string command, params object[] args)
{
_dictionary[command].Invoke(args);
}
}
The following scenario would allow you to use a dictionary of elements to send in as input parameters and get the same as the output parameters.
First add the following line at the top:
using TFunc = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Collections.Generic.IDictionary<string, object>>;
Then inside your class, define the dictionary as follows:
private Dictionary<String, TFunc> actions = new Dictionary<String, TFunc>(){
{"getmultipledata", (input) =>
{
//DO WORKING HERE
return null;
}
},
{"runproc", (input) =>
{
//DO WORKING HERE
return null;
}
}
};
This would allow you to run these anonymous functions with a syntax similar to this:
var output = actions["runproc"](inputparam);
Why not use params object[] list for method parameters and do some validation inside either your methods (or calling logic), It will allow for a variable number of parameters.

o => o.MethodWithParameters | is it possible to use a method in a lambda without () and parameters

i have a method that takes as a parameter an expression because I need the method string name, and I don't care about the parameters of that method, is it possible to do that ?
I don't think that there is. You can however make a generic helper method that you can put in place of the parameters:
public T Any<T>(){
return default(T);
}
and you can call it like so:
YourMethod((YourClass yc) => yc.SomeMethod(Any<SomeClass>(), Any<SomeOtherClass>());
Yes, it's possible. Here is a concept proof test.
private static T RunExpression<T>(Expression<Func<T>> run )
{
var callExpression = (MethodCallExpression) run.Body;
var procedureName = callExpression.Method.Name;
Trace.WriteLine(procedureName);
foreach (var argument in callExpression.Arguments)
{
Trace.WriteLine(argument);
}
Trace.WriteLine(callExpression.Arguments.Count);
// Some really wicked stuff to assign out parameter
// Just for demonstration purposes
var outMember = (MemberExpression)callExpression.Arguments[1];
var e = Expression.Lambda<Func<object>>(outMember.Expression);
var o = e.Compile().Invoke();
var prop = o.GetType().GetField("s");
prop.SetValue(o, "Hello from magic method call!");
Trace.WriteLine(run.Body);
return default(T);
}
[TestMethod]
public void TestExpressionInvocation()
{
var action = new MyActionObject();
string s = null;
RunExpression(() => action.Create(1, out s));
Assert.AreEqual("Hello from magic method call!", s);
}
The easiest way to do this doesn't even use expression trees:
void Main()
{
Console.Out.WriteLine(GetNameOfMethod(new Action(Main)));
Console.Out.WriteLine(GetNameOfMethod(new Func<Delegate, string>(GetNameOfMethod)));
Console.Out.WriteLine(GetNameOfMethod(new Func<int, short, long>(AddNumber)));
Console.Out.WriteLine(GetNameOfMethod(new Action<int, short>(SwallowNumber)));
}
string GetNameOfMethod(Delegate d){
return d.Method.Name;
}
long AddNumber(int x, short y){ return x+y; }
void SwallowNumber(int x, short y){}
yields:
Main
GetNameOfMethod
AddNumber
SwallowNumber
I use this to build a BDD framework on http://storyq.codeplex.com.
Click here to see the file where I do this.
You can use this method without parameters but parentheses (even empty) are required, because without them you tell the compiler to access a property of that name.
You can use something like:
(credits go to klausbyskov)
But it's less verbose.
Also you will need to provide overloads for various argument lists.
[TestClass]
public class TestExpressions
{
public class MyClass
{
public bool MyMethod(string arg)
{
throw new NotImplementedException();
}
}
private static string UseExpression<T, Ta1>(Expression<Action<T,Ta1>> run)
{
return ((MethodCallExpression)run.Body).Method.Name;
}
[TestMethod]
public void TestExpressionParser()
{
Assert.AreEqual("MyMethod",
UseExpression<MyClass,string>((c,fakeString) => c.MyMethod(fakeString)));
}
}

Categories