【问题标题】:Appending string to <T> to produce a new class name将字符串附加到 <T> 以生成新的类名
【发布时间】:2012-11-04 00:56:06
【问题描述】:

如何将字符串附加到类型名称然后将其作为另一种类型传递?这是一个例子:

 public T Get<T>(int id)
        {
           return dbAccess.Get<T>(id);
        }

如果我像这样调用这个方法

SomeObject.Get<Class1>(1234);

我想通过将字符串“Data”附加到任何传递的类来将Class1 更改为Class1Data,因此dbAccess.Get 方法会将对象作为Class1Data 作为Class1 的转换。

【问题讨论】:

  • 泛型不应该这样使用。泛型只是编译器在稍后阶段提供的实际类型的占位符。从表面上看,您使用的技术不适合像 C# 这样的强类型语言。如果您无法避免这种情况,我建议您按照 Jon 的建议行事。

标签: c# .net reflection casting type-conversion


【解决方案1】:

这样的事情会起作用:

public T Get<T>(int id)
    {
        var newTypeName = typeof(T).FullName + "Data";
        var newType = Type.GetType(newTypeName);
        var argTypes = new [] { newType };
        var method = GetType().GetMethod("Get");
        var typedMethod = method.MakeGenericMethod(argTypes);
        return (T) typedMethod.Invoke(this, new object[] { id });
    }

如果您的 XxxData 对象不是从 Xxx 继承的,您可能需要在返回结果之前进行一些自动映射。

那么你必须将最后一行替换为:

        var dataResult = typedMethod.Invoke(this, new object[] { id });
        var result = new T(); // You will have to add a new() constraint on generic parameter
        // Map your dataResult object's values onto the result object's values
        return result;

【讨论】:

    【解决方案2】:

    这是不可能的,因为在编译时必须知道所有类型参数。只要这两种方法都是通用的,你就无能为力了。

    通常这种翻译是通过切换到反射和运行时处理来进行的;例如,方法的签名不是DbAccess.Get&lt;T&gt;(int),而是DbAccess.Get(Type, int)

    【讨论】:

      【解决方案3】:

      泛型参数 T 是编译时参数。换句话说,编译器在编译时对你的代码进行预处理,此时类型变得固定。

      因此,您不能在运行时更改用于 T 的类型。

      如果您有一组受限制的类型,一种方法是设置对每个类型的调用,然后根据字符串在它们之间切换,例如

      switch (str)
      {
          case "":
              SomeObject.Get<Class1>(1234);
              break;
      
          case "Data":
              SomeObject.Get<Class1Data>(1234);
              break;
      }
      

      或者您可以完全放弃泛型并改用反射。

      【讨论】:

      • 很遗憾这样不行,转换背后的原因是自动将业务类型更改为数据类型,传递给这个调用的每个类都需要转换为其他数据类名称,我所有的业务都是与附加字符串“Data”的数据类相同,Employee 是 EmployeeData 等等。
      • 为什么要抛弃泛型,你也可以用反射来使用它们(见我的回答)。
      • @Rene Wolferink,现在 Maya 已经解释了这样做的全部目的,你的回答很有意义。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 2014-04-17
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      相关资源
      最近更新 更多