将字符串附加到<t>以生成新的类名</t>

时间:2012-11-15 12:10:14

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

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

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

如果我将此方法称为

SomeObject.Get<Class1>(1234);

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

3 个答案:

答案 0 :(得分:3)

这样的事情会起作用:

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;

答案 1 :(得分:1)

通用参数T是编译时参数。换句话说,编译器在编译时预处理您的代码,此时类型变得固定。

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

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

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

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

或者你可以完全抛弃泛型并改为使用反射。

答案 2 :(得分:1)

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

通常这种转换是通过切换到反射和运行时处理来执行的;例如,代替方法的签名为DbAccess.Get<T>(int),它必须是DbAccess.Get(Type, int)