指定可由编译器验证的方法名称(用于反射)
本文关键字:用于 反射 方法 编译器 验证 | 更新日期: 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;
}