1

基本上我想这样做:

Func<string> f =  ()=> MyMethodName();

仅具有方法的字符串名称,即:

 Func<string> f =  "MyMethodName";

这可以做到吗?有什么问题,注意事项?反射可以帮助吗?我可以先检查一个方法是否存在吗?

4

3 回答 3

6

这里根本不需要 lambda 表达式。您可以使用Delegate.CreateDelegate

MethodInfo method = GetType().GetMethod(methodName);
Func<string> func = (Func<string>) Delegate.CreateDelegate(typeof(Func<string>),
                                                           obj, method);

这样,您就可以避免一定程度的间接性,并且您还可以进行一次反射部分,而不是每次调用。

于 2012-09-25T22:49:46.890 回答
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

于 2012-09-25T22:29:22.173 回答
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 并将读取的所有数据复制到类的集合中,其中类上的属性名称与读取器中的字段匹配。

请注意,约翰的回答是一种更简单的方法,直到现在我才知道,但我想这有更大的灵活性

于 2012-09-25T22:51:12.723 回答