基本上我想这样做:
Func<string> f = ()=> MyMethodName();
只有一个方法的字符串名称,即:
Func<string> f = "MyMethodName";
可以这样做吗?任何问题,警告?反思有帮助吗?我可以先检查方法是否存在吗?
答案 0 :(得分:6)
这里根本不需要lambda表达式。您可以使用Delegate.CreateDelegate
:
MethodInfo method = GetType().GetMethod(methodName);
Func<string> func = (Func<string>) Delegate.CreateDelegate(typeof(Func<string>),
obj, method);
这样你可以避免间接级别,并且你也可以在中执行反射部分而不是每次调用。
答案 1 :(得分:2)
以下是反思的例子:
Func<string> func = ( ) => {
return ( string )( this.GetType( ).GetMethod( "MyMethodName" ).Invoke( this, new object[ 0 ] ) );
}
如果你想要一些东西来缓解这件事,那就是:
public static Func<string> ReflectByName( object obj, string methodname ) {
return ( ) => {
return ( string )( obj.GetType( ).GetMethod( methodname ).Invoke( obj, new object[ 0 ] ) );
}
}
使用方法:
Func<string> f = FastReflect.ReflectByName( this, "MyMethodName" );
FastReflect
方法ReflectByName
所在的位置。
答案 2 :(得分:0)
这是另一种方法。这样做的优点是比反射快得多,所以如果需要在循环中调用它,那就太好了。此代码创建一个将调用方法
的Func public static Func<T, string> CreateCallFunc<T>(string methodName)
{
var parm = Expression.Parameter(typeof(T));
var call = Expression.Call(parm, typeof(T).GetMethod(methodName));
var lambda = Expression.Lambda<Func<T, string>>(call, parm);
return (Func<T, string>)lambda.Compile();
}
你这样使用它:
class SomeClass
{
void DoIt()
{
var func = CreateCallFunc<SomeClass>("SomeMethod");
Console.WriteLine(func(this));
}
public string SomeMethod()
{
return "it works!";
}
}
最大的好处是,一旦你创建了你的Func,你只需使用func(myInstance)就可以非常简单地调用它,它会非常快。
我使用此方法获取DataReader并将读取中的所有数据复制到类的集合中,其中类的属性名称与读取器中的字段匹配。
请注意,约翰的答案是一种更容易实现的方法,直到现在我才知道这一点,但我认为这具有更大的灵活性