通用方法使用运行时类型执行

时间:2009-10-22 12:46:09

标签: c# generics methods

我有以下代码:

 public class ClassExample
{

    void DoSomthing<T>(string name, T value)
    {
        SendToDatabase(name, value);
    }

    public class ParameterType
    {
        public readonly string Name;
        public readonly Type DisplayType;
        public readonly string Value;

        public ParameterType(string name, Type type, string value)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");
            if (type == null)
                throw new ArgumentNullException("type");

            this.Name = name;
            this.DisplayType = type;
            this.Value = value;
        }
    }

    public void GetTypes()
    {
        List<ParameterType> l = report.GetParameterTypes();

        foreach (ParameterType p in l)
        {
            DoSomthing<p.DisplayType>(p.Name, (p.DisplayType)p.Value);
        }

    }
}

现在,我知道我无法执行DoSomething() 还有其他方法可以使用这个功能吗?

5 个答案:

答案 0 :(得分:35)

你可以,但它涉及反思,但你可以做到。

typeof(ClassExample)
    .GetMethod("DoSomething")
    .MakeGenericMethod(p.DisplayType)
    .Invoke(this, new object[] { p.Name, p.Value });

这将查看包含类的顶部,获取方法信息,创建具有适当类型的泛型方法,然后可以在其上调用Invoke。

答案 1 :(得分:5)

this.GetType().GetMethod("DoSomething").MakeGenericMethod(p.Value.GetType()).Invoke(this, new object[]{p.Name, p.Value});

应该工作。

答案 2 :(得分:3)

无法在运行时以您希望的方式指定泛型类型。

最简单的选项是添加DoSomething的非泛型重载,或者只需调用DoSomething<object>并忽略p.DisplayType。除非SendToDatabase取决于value编译时类型(并且它可能不应该),否则给它object应该没有错。

如果你不能这样做,你将不得不使用反射来呼叫DoSomething,你会受到很大的打击。

答案 3 :(得分:3)

首先我们需要将p.Value转换为正确的类型,因为即使我们在编译时知道类型,我们也无法将字符串直接传递给方法...

DoSomething<Int32>( "10" ); // Build error

对于简单的数字类型和DateTime,我们可以使用

object convertedValue = Convert.ChangeType(p.Value, p.DisplayType);

现在我们可以使用反射来调用所需的泛型方法......

typeof(ClassExample)
    .GetMethod("DoSomething")
    .MakeGenericMethod(p.DisplayType)
    .Invoke(this, new object[] { p.Name, convertedValue });

答案 4 :(得分:1)

严格地说,您可以使用MethodInfo.MakeGenericMethod

但我建议将DoSomething改为非泛型形式,因为它是否真的应该是通用的并不明显。