1

给定静态类:

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使用反射调用 Gold?这是我到目前为止所拥有的:

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

编辑:

我应该提到我计划在我的Converters类中添加其他可能采用不同参数的 Funcs。

Edit2: 从到目前为止的回复来看,我认为它适用于Func下面的 Gold。我想我现在的问题是,当我不知道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));
4

2 回答 2

3

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

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

您还可以通过使用GetFieldif 它永远不会是一个属性来简化它:

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并完全避免反射的可能性。

于 2012-11-29T23:10:35.717 回答
2

由于它不是函数或属性,因此您不能这样调用成员。您应该首先获取它的值,根据需要对其进行转换,然后才调用结果,如下所示:

var converter = typeof(Converters).GetField(regEx.Converter);
var f = converter.GetValue(null) as Func<long,string>;
var matchedValueString = f(matchedValueInt);
于 2012-11-29T23:07:29.183 回答