1

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

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

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

SomeObject.Get<Class1>(1234);

我想通过将字符串“Data”附加到任何传递的类来更改Class1为,因此该方法会将对象作为.Class1DatadbAccess.GetClass1DataClass1

4

3 回答 3

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;
于 2012-11-15T12:23:16.643 回答
1

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

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

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

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

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

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

于 2012-11-15T12:13:52.453 回答
1

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

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

于 2012-11-15T12:22:49.233 回答