【问题标题】:Using a System.Type as a Generic Parameter for a Method [duplicate]使用 System.Type 作为方法的通用参数
【发布时间】:2020-07-31 03:08:31
【问题描述】:

如何为这样的事情创建一个通用方法

Type myType = Type.GetType(classNameType.AssemblyQualifiedName);  --gets the required type

CustomerWrapper.DeserializeJsonFromStream<myType>(stream); -- failing here

我想在上面的行中传递不同的类型,但出现错误说“myType 是可变的,但用作类型”。我该如何解决这个问题?

【问题讨论】:

  • 我不知道DeserializeJsonFromStream 方法是什么样的,但有时他们有相同方法的重载版本,应该看起来像DeserializeJsonFromStream(Stream stream, Type ofType)。你有没有看到类似的东西?

标签: c# .net


【解决方案1】:

您无法做到这一点开箱即用泛型需要在编译时知道,以便编译器可以生成适当的IL生成的类.

但是,您可以使用 reflection 和一些 tomfoolery(考虑到通常的反射性能影响)。这是一个过于人为的例子

给定

public class CustomerWrapper
{
   public void DeserializeJsonFromStream<T>(Stream stream)
     => Console.WriteLine(typeof(T).Name);
}

用法

var wrapper = new CustomerWrapper();
var stream = new MemoryStream();

var myType = typeof(string);

var method = typeof(CustomerWrapper).GetMethod(nameof(CustomerWrapper.DeserializeJsonFromStream));

if (method == null) 
   throw new MissingMethodException(nameof(CustomerWrapper),nameof(CustomerWrapper.DeserializeJsonFromStream));

var genericType = method.MakeGenericMethod(myType);
genericType.Invoke(wrapper, new object[]{stream});

输出

String

或者,如果你觉得幸运并且喜欢一行中的所有内容

var method = typeof(CustomerWrapper)
    .GetMethod(nameof(CustomerWrapper.DeserializeJsonFromStream))
    .MakeGenericMethod(myType)
    .Invoke(wrapper, new object[] {stream});

注意:值得指出的是,大多数反序列化方法中通常都有一个类型参数Deserialize(String, Type, JsonSerializerOptions),因此您可能会更好地使用它们


其他资源

Type.GetMethod Method

获取当前Type的特定方法。

MethodInfo.MakeGenericMethod(Type[]) Method

用类型数组的元素替换类型参数 当前泛型方法定义,并返回 MethodInfo 表示生成的构造方法的对象。

MethodBase.Invoke Method

调用此 MethodInfo 所反映的方法或构造函数 实例。

【讨论】:

    猜你喜欢
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多