指定可由编译器验证的方法名称(用于反射)

本文关键字:用于 反射 方法 编译器 验证 | 更新日期: 2023-09-27 18:18:02

我想调用一个方法并提供一些参数(我从返回名称:值对的过滤器控件获得)给它。

如果我有一个方法(对象obj) string Foo(int bar, double baz)和一个字典{'bar':3,'baz':1.4},我想写

string s = Call<string>(obj,p=>p.Foo,dictionary)

有可能吗?非泛型委托之类的?或者使用多个泛型的Func静态方法来利用c#类型推断?

现在我有这样的东西:

    string s = Call<string>(obj,"Foo",parameters)

被实现为:

    TRet Call<TRet>(object target, string name, Dictionary<string, object> parameters) where TRet:class
    {
        var mi = target.GetType().GetMethod(name);
        object[] methodParameters = ConvertDictionaryToParameterArray(parameters);
        object o = mi.Invoke(target, methodParameters);
        return o as TRet;
    }

TRet调用(对象目标,字符串名称,字典参数)

在其他地方,我们有一些基于反射的技巧,将名为Prop1,Prop2,Prop3,Prop4的属性收集到数组Prop[]中,并且可以像Collect(data, p=>Prop1)一样调用方法,将方法Collect定义为Wrapper<T> Collect<T>(T item, Expression<Func<T,int>> expr),将expr表达式分析为MemberExpression。

指定可由编译器验证的方法名称(用于反射)

你能得到的最接近的可能是:

List<string> list = new List<string>();
MethodInfo sort = Infoof(() => list.Sort());
MethodInfo binarySearch = Infoof(() => list.BinarySearch(null, null));
public static MethodInfo Infoof(Expression<Action> exp)
{
    return ((MethodCallExpression)exp.Body).Method;
}

这有点冗长,因为你实际上需要创建一个lambda来调用你需要的方法(注意它从来没有实际执行调用本身)。

更多细节:http://codebetter.com/patricksmacchia/2010/06/28/elegant-infoof-operators-in-c-read-info-of/

编辑:如果它是一个没有返回值的静态方法,你知道输入/输出类型,或者你不介意显式指定它们,你也可以这样做:

MethodInfo write = ActionInfo(Console.WriteLine);
MethodInfo empty = FuncInfo(string.IsNullOrEmpty);
MethodInfo emptyT = FuncInfoT<string, bool>(string.IsNullOrEmpty);
public static MethodInfo ActionInfo(Action act)
{
    return act.Method;
}
public static MethodInfo FuncInfo(Func<string, bool> fn)
{
    return fn.Method;
}
public static MethodInfo FuncInfoT<T1, T2>(Func<T1, T2> fn)
{
    return fn.Method;
}