C# 将常规方法链接到委托
我希望能够将一个方法链接到所有类型的委托。我正试图通过C# 将常规方法链接到委托,c#,delegates,reflection.emit,C#,Delegates,Reflection.emit,我希望能够将一个方法链接到所有类型的委托。我正试图通过refelection.emit来实现这一点,并将动态方法与delagate的示意图相链接,将其添加到委托中,让此动态方法调用具有所有参数的常规函数。但我希望有一个更简单的方法来做到这一点 (我没有包括反射.emit代码,因为这不是我想要的帮助,这仍然是一个原始的尝试) 这是我想要得到的结果的一个例子: public class FooClass { public delegate string MyFirstDele
refelection.emit
来实现这一点,并将动态方法与delagate的示意图相链接,将其添加到委托中,让此动态方法调用具有所有参数的常规函数。但我希望有一个更简单的方法来做到这一点
(我没有包括反射.emit
代码,因为这不是我想要的帮助,这仍然是一个原始的尝试)
这是我想要得到的结果的一个例子:
public class FooClass
{
public delegate string MyFirstDelegate(string input1, string input2);
public delegate int MySecondDelegate(int input1, string input2, short input3);
public static MyFirstDelegate firstDelegate = null;
public static MySecondDelegate SecondDelegate = null;
private static string FirstMethod(string input1, string input2)
{
return input1 + input2;
}
private static int SecondMethod(int input1, string input2, short input3)
{
return input1 + Convert.ToInt32(input2) + input3;
}
private static object ThirdMethod(params object[] inputs)
{
//do some magic and return result
}
public static void Main()
{
firstDelegate = FirstMethod;
SecondDelegate = SecondMethod;
string result = firstDelegate("1", "2");
int result2 = SecondDelegate(1, "3", 3);
//obviously this does not work, but is there a way to link this method to the delegate?
firstDelegate = ThirdMethod;
SecondDelegate = ThirdMethod;
string result3 = firstDelegate("1", "2");
int result4 = SecondDelegate(1, "3", 3);
}
}
要将方法链接到所有类型的委托,可以使用
Expression
创建助手方法,如下所示:
private static TTarget ConvertDelegate<TTarget>(MethodInfo source)
{
var targetMethod = typeof(TTarget).GetMethod("Invoke");
var parameters = targetMethod.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name)).ToArray();
var methodCall = Expression.Call(source, Expression.NewArrayInit(typeof(object), parameters));
var delegateExpression = Expression.Lambda<TTarget>(Expression.TypeAs(methodCall, targetMethod.ReturnType), parameters);
return delegateExpression.Compile();
}
var methodInfo= typeof(FooClass).GetMethod(nameof(ThirdMethod), BindingFlags.NonPublic | BindingFlags.Static);
firstDelegate = ConvertDelegate<MyFirstDelegate>(methodInfo);
firstDelegate = ConvertDelegate<MyFirstDelegate, FooClass>(nameof(ThirdMethod));
然后你可以这样使用它:
private static TTarget ConvertDelegate<TTarget>(MethodInfo source)
{
var targetMethod = typeof(TTarget).GetMethod("Invoke");
var parameters = targetMethod.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name)).ToArray();
var methodCall = Expression.Call(source, Expression.NewArrayInit(typeof(object), parameters));
var delegateExpression = Expression.Lambda<TTarget>(Expression.TypeAs(methodCall, targetMethod.ReturnType), parameters);
return delegateExpression.Compile();
}
var methodInfo= typeof(FooClass).GetMethod(nameof(ThirdMethod), BindingFlags.NonPublic | BindingFlags.Static);
firstDelegate = ConvertDelegate<MyFirstDelegate>(methodInfo);
firstDelegate = ConvertDelegate<MyFirstDelegate, FooClass>(nameof(ThirdMethod));
firstDelegate=ConvertDelegate(nameof(ThirdMethod));
不要忘记,
ConvertDelegate
将只包装带有签名的方法对象名(对象[]输入)
,如果您只需要包装一个方法,您可以将MethodInfo
保存在某个局部值中,而不是每次都作为参数传递。要将方法链接到所有类型的委托,您可以使用表达式创建助手方法,如下所示:
private static TTarget ConvertDelegate<TTarget>(MethodInfo source)
{
var targetMethod = typeof(TTarget).GetMethod("Invoke");
var parameters = targetMethod.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name)).ToArray();
var methodCall = Expression.Call(source, Expression.NewArrayInit(typeof(object), parameters));
var delegateExpression = Expression.Lambda<TTarget>(Expression.TypeAs(methodCall, targetMethod.ReturnType), parameters);
return delegateExpression.Compile();
}
var methodInfo= typeof(FooClass).GetMethod(nameof(ThirdMethod), BindingFlags.NonPublic | BindingFlags.Static);
firstDelegate = ConvertDelegate<MyFirstDelegate>(methodInfo);
firstDelegate = ConvertDelegate<MyFirstDelegate, FooClass>(nameof(ThirdMethod));
然后你可以这样使用它:
private static TTarget ConvertDelegate<TTarget>(MethodInfo source)
{
var targetMethod = typeof(TTarget).GetMethod("Invoke");
var parameters = targetMethod.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name)).ToArray();
var methodCall = Expression.Call(source, Expression.NewArrayInit(typeof(object), parameters));
var delegateExpression = Expression.Lambda<TTarget>(Expression.TypeAs(methodCall, targetMethod.ReturnType), parameters);
return delegateExpression.Compile();
}
var methodInfo= typeof(FooClass).GetMethod(nameof(ThirdMethod), BindingFlags.NonPublic | BindingFlags.Static);
firstDelegate = ConvertDelegate<MyFirstDelegate>(methodInfo);
firstDelegate = ConvertDelegate<MyFirstDelegate, FooClass>(nameof(ThirdMethod));
firstDelegate=ConvertDelegate(nameof(ThirdMethod));
不要忘记,ConvertDelegate
将只包装带有签名的方法对象名称(对象[]输入)
,如果只需要包装一个方法,您可以将MethodInfo
保存在一些局部值中,而不是每次都作为参数传递