【问题标题】:How to do a generic call to function based on a Type object? [duplicate]如何基于 Type 对象对函数进行通用调用? [复制]
【发布时间】:2011-09-22 13:29:16
【问题描述】:

你如何执行Get,当你只有:T表示为一个Type对象,即

Type type=typeof(int);

还有参数 param1 和 param2?

    public void DoCall(){
        var type=typeof(int);
        // object o=Get<type> ("p1","p2");   //<-- wont work (expected)
        // *** what should go here? ***
    }

    public IEnumerable<T> Get<T>(string param1,string param2) {
        throw new NotImplementedException();
    }

【问题讨论】:

  • 这种泛型方法是为了编译时的类型安全。如果您在编译时不知道类型,则很有可能您使用了错误的泛型,或者应该有一个额外的重载,该重载将类型作为参数,例如public IEnumerable Get(Type type, string param1, string param2)
  • @Jamiec:感谢 Jamiec 的评论。我会记住这一点。保留 的一个原因是我想尽可能使用 。在这种情况下,我不得不放弃 的用法,或者采用两个方法签名(一个带有 ,另一个带有 Get(Type typ, ...)
  • @sgtz - 有两种方法是处理这两种可能性的通常方法。这是大多数 DA 库处理这种情况的方式。

标签: c# .net-4.0


【解决方案1】:

你需要使用反射:

public IEnumerable GetBoxed(Type type, string param1, string param2)
{
    return (IEnumerable)this
        .GetType()
        .GetMethod("Get")
        .MakeGenericMethod(type)
        .Invoke(this, new[] { param1, param2 });
}

【讨论】:

    【解决方案2】:

    MakeGenericMethod 是关键:

    var get = typeof(WhereverYourGetMethodIs).GetMethod("Get");
    var genericGet = get.MakeGenericMethod(type);
    

    【讨论】:

    • +1 看起来很接近。我们是否也应该为“MakeGenericMethod”提供参数?
    【解决方案3】:

    直接使用泛型类型参数有什么问题?

    public void DoCall(){
        IEnumerable<int> integers = Get<int> ("p1","p2");
        // ...
    }
    

    【讨论】:

      【解决方案4】:

      在上面的示例中,“T”将是您传递给 Get 方法的任何内容,它还将返回相同的 IEnumerable。因此,如果您执行以下操作:

       IEnumerable<int> o = Get<int>("p1", "p2");
      

      o 将是 IEnumerable

      但是如果你想要别的东西,那么你只需传入不同的类型,因此是通用类型。

      【讨论】:

        【解决方案5】:

        如果可能,您应该重新定义 Get 方法以将对象类型作为参数:

        public IEnumerable<object> Get(object type, string param1,string param2)
        {
        }
        

        那么如果真的需要的话,可以把原来的泛型方法改写如下:

        public IEnumerable<T> Get<T>(string param1,string param2)
        {
            var result = Get(typeof(T), param1, param2);
            return result.Cast<T>();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-07-11
          • 1970-01-01
          • 2018-11-24
          • 2020-03-31
          • 1970-01-01
          • 2023-04-04
          • 1970-01-01
          相关资源
          最近更新 更多