【问题标题】:Construct class using string name for generic parameter使用泛型参数的字符串名称构造类
【发布时间】:2016-05-06 06:19:06
【问题描述】:

我有一个使用这样的通用参数创建的 Json 反序列化器类:

Deserializer<T> results = Deserializer<T>.FromFile(file);

其中 T 是任意数量的类型实现的接口。

我希望以字符串形式的类名选择 T,例如“Person” Person 类实现了 T。

所以可以这样写:

Deserializer<Type.GetType("Person")> results = Deserializer<Type.GetType("Person")>.FromFile(file);

我已经在上面尝试过,但它给了我一个错误:

Using the generic type 'Deserializer<T>' requires 1 type arguments

我也看过这个

http://social.msdn.microsoft.com/Forums/en-US/80690cd9-d1f2-4888-9c95-62305de9ced4/using-typegettype-with-generics

但尝试使用其中一些会导致其他错误,例如:

randomVariable is a 'field' but is used like a 'type'

我的代码有错误还是我的处理方式不对?

我怎样才能让它工作?

解决方案 我的最终代码是

        Type genericType = typeof(Deserializer<>);
        Type[] typeArgs = {Type.GetType("Person")};
        Type deserialiserType = genericType.MakeGenericType(typeArgs);
        object repository = Activator.CreateInstance(deserialiserType);

        MethodInfo genericMethod = deserialiserType.GetMethod("FromFile");
        genericMethod.Invoke(repository, new[] {file});

谢谢大家的帮助

【问题讨论】:

  • 你能否详细说明你的目标,你所说的并不完全是计算出来的。您是在尝试基于 JSON 构建 interfaceclass,还是尝试将值分配给存在的类?
  • 告诉我们您使用的是什么序列化程序,以便我们给您一些建议。
  • 如果提供的类名实现了多个接口怎么办?
  • 我认为这对您可能非常有用:stackoverflow.com/questions/11107536/…。出自乔恩·斯基特的口中!
  • @barrick 我可以保证它只实现一次类。

标签: c# generics


【解决方案1】:

使用应用到您的代码的 ModiX 链接中的答案,应该会产生如下结果:

Type genericType = typeof(Deserializer<>);
Type[] typeArgs = { Type.GetType("Person") };
Type deserializerType = genericType.MakeGenericType(typeArgs);

object deserializer = Activator.CreateInstance(deserializerType);

MethodInfo fromFileMethod = deserializerType.GetMethod("FromFile");
fromFileMethod.Invoke(deserializer, new[] { file });

线

MethodInfo closedMethod = genericMethod.MakeGenericMethod(typeof(Something));

如果您的方法是通用的,则使用它,在您的情况下,如果它看起来像这样:

Deserializer<T>.FromFile<T2>(...)

【讨论】:

    【解决方案2】:

    这是错误的方法,因为泛型字段需要类型而不是 Type 类的对象。

    但是,已经有解决方案了。 How do I create a generic class from a string in C#?

    【讨论】:

    • 感谢您的链接,这让我一直走到了这条线上:MethodInfo closedMethod = genericMethod.MakeGenericMethod(typeof(Something)); 但我不知道Something是什么,这让我回到了原来的问题
    • 谢谢,当我可以使用 genericMethod 选项调用该方法时,我走得太远了
    【解决方案3】:

    泛型参数必须是“真实类型名称”,因为它们应该在构建时可解析。

    Type.GetType 是一个运行时方法。

    你有很多选择,例如:

    这将使您能够使用运行时类型。

    • 查看反序列化器是否可以“自动”反序列化为良好类型的实例(装箱在对象中),然后将其转换为预期的类型。

    • 根据要反序列化的数据,更改您的实现以使用良好的通用参数调用 Deserializer。

    【讨论】:

      【解决方案4】:

      我相信你试图做的是实现这个:

      public interface Dynamic <T>
      {
           T GetObject(string derserialize);
      }
      

      所以基本上你的类会继承Dynamic,在那个时候定义你的泛型类型。然后,您将基本上隐式显式实现方法GetObject。它会接受您的 JSON 数据,然后您可以执行所需的逻辑以将其作为您选择的 type 返回。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多