基本上我想这样做:
Func<string> f = ()=> MyMethodName();
仅具有方法的字符串名称,即:
Func<string> f = "MyMethodName";
这可以做到吗?有什么问题,注意事项?反射可以帮助吗?我可以先检查一个方法是否存在吗?
这里根本不需要 lambda 表达式。您可以使用Delegate.CreateDelegate
:
MethodInfo method = GetType().GetMethod(methodName);
Func<string> func = (Func<string>) Delegate.CreateDelegate(typeof(Func<string>),
obj, method);
这样,您就可以避免一定程度的间接性,并且您还可以进行一次反射部分,而不是每次调用。
这是一个反射的例子:
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
。
这是另一种方法。这具有比反射快得多的优点,因此如果您需要在循环中调用它,那就太好了。此代码创建一个 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 并将读取的所有数据复制到类的集合中,其中类上的属性名称与读取器中的字段匹配。
请注意,约翰的回答是一种更简单的方法,直到现在我才知道,但我想这有更大的灵活性