我希望我遗漏了一些明显的东西,但我在定义一个方法时遇到了一些麻烦,该方法采用方法的参数来获取传递的方法的方法信息。我不想实际执行该方法。
我希望能够做到:
busObject.SetResolverMethod<ISomeInterface>(x=>x.GetNameById);
其中 GetNameById 是在接口(interface) ISomeInterface 上定义的方法。在这种情况下,传入签名的方法示例如下:
MyVarA GetNameById(int id){ .... }
在上面的示例中,SetResolverMethod 的主体应该能够返回/存储字符串“GetNameById”。
传入的方法没有标准签名(除了它总是返回某种对象)。
目前我将方法设置为字符串(即“GetNameById”),但我希望它在编译时进行检查,因此出现了这个问题。
最佳答案
它不是特别漂亮/流畅,但如果您真的想避免必须传递虚拟参数值,那么您可以使用返回委托(delegate)的表达式。
SetResolverMethod<ISomeInterface>(x => new Func<int, MyVarA>(x.GetNameById));
SetResolverMethod
实现看起来像这样:
public void SetResolverMethod<T>(Expression<Func<T, Delegate>> expr)
{
var unary = (UnaryExpression) expr.Body;
var methodCall = (MethodCallExpression) unary.Operand;
var constant = (ConstantExpression) methodCall.Arguments[2];
var method = (MethodInfo) constant.Value;
Console.WriteLine(method.Name);
}
编辑:如果您愿意为每个 Func<>
创建一组重载delegate,你可以通过在方法的泛型参数类型中包含方法参数类型来提高流畅度。
p.SetResolverMethod<ISomeInterface, int, MyVarA>(x => x.GetNameById);
如您所见,调用方不再需要指定委托(delegate)类型,从而节省了大约 8 个字符。
我已经为 0、1 和 2 参数实现了三个重载:
public void SetResolverMethod<T, TResult>(Expression<Func<T, Func<TResult>>> expr)
{
SetResolverMethod((LambdaExpression) expr);
}
public void SetResolverMethod<T, T1, TResult>(Expression<Func<T, Func<T1, TResult>>> expr)
{
SetResolverMethod((LambdaExpression) expr);
}
public void SetResolverMethod<T, T1, T2, TResult>(Expression<Func<T, Func<T1, T2, TResult>>> expr)
{
SetResolverMethod((LambdaExpression) expr);
}
private void SetResolverMethod(LambdaExpression expr)
{
var unary = (UnaryExpression) expr.Body;
var methodCall = (MethodCallExpression) unary.Operand;
var constant = (ConstantExpression) methodCall.Arguments[2];
var method = (MethodInfo) constant.Value;
Console.WriteLine(method.Name);
}
关于c# - .NET Lambda 传递方法参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2941076/