使用反射从静态类调用静态Func

时间:2012-11-29 23:03:13

标签: c# .net reflection

给出静态类:

public static class Converters
{
    public static Func<Int64, string> Gold = c => String.Format("{0}g {1}s {2}c", c/10000, c/100%100, c%100);
}

我从数据库中收到Func名称作为字符串(regEx.Converter)。如何使用反射调用黄金Func?以下是我到目前为止的情况:

var converter = typeof(Converters).GetMember(regEx.Converter);
if (converter.Count() != 1)
{
    //throw new ConverterNotFoundException;
}                    
matchedValue = converter.Invoke(null, new object[]{matchedValue}) as string;

修改

我应该提到我计划将其他Func添加到我的Converters类中,这可能会采用不同的参数。

EDIT2: 从目前为止的回复中,我已经为下面的黄金Func工作了。我想我现在的问题是,当我不知道Func的参数时,我该如何工作呢?例如,我可能想要创建另一个转换器:Func<string, string>。我唯一可以肯定的是,只有一个参数(不同类型),返回将始终是字符串。

var converter = typeof(Converters).GetField("w", BindingFlags.Static | BindingFlags.Public);
if (converter == null)
{
    //throw new ConverterNotFoundException;
}
var f = converter.GetValue(null) as Func<Int64, string>;
matchedValue = f.Invoke(Convert.ToInt64(matchedValue));

2 个答案:

答案 0 :(得分:3)

您需要指定BindingFlags以获取静态成员:

var converter = typeof(Converters).GetMember(regEx.Converter,
    BindingFlags.Static | BindingFlags.Public);

如果它永远不是属性,您也可以使用GetField来简化此操作:

FieldInfo converter = typeof(Converters).GetField(regEx.Converter,
    BindingFlags.Static | BindingFlags.Public);

编辑:
我不确定它会有多大帮助,因为你仍然需要知道传递Func<>的参数是什么类型,但是这样可以让你调用Func<>而无需投射它:

var matchedValue = converter.GetValue(null);
matchedValue.GetType().GetMethod("Invoke")
    .Invoke(matchedValue, new object[] { Convert.ToInt64(0) });

获取参数的类型:

matchedValue.GetType().GetGenericArguments()[0];

你应该考虑更容易switch字段名称并完全避免反思。

答案 1 :(得分:2)

由于它不是函数或属性,因此您无法像这样调用成员。您应该首先获取其值,然后根据需要进行投射,然后再调用结果,如下所示:

var converter = typeof(Converters).GetField(regEx.Converter);
var f = converter.GetValue(null) as Func<long,string>;
var matchedValueString = f(matchedValueInt);