在运行时生成通用类型

时间:2011-02-20 20:56:48

标签: c# generics reflection types runtime

我想知道是否可以使用一个变量的类型设置为另一个泛型变量的类型?

例如,假设我有这段代码:

public class Foo: IBar<ushort>
{
    public FooBar()
    {
        Value = 0;
    }

    public ushort Value { get; private set; }
}

我也有这个课程:

public class FooDTO<TType> : IBar<TType>
{
    public TType Value { get; private set; }
}

在这些示例中,IBar的界面具有属性

TType Value;

然后在我的代码中我有这个

var myFoo = new Foo();
var fooDataType = myFoo.Value.GetType();

//I know this line of code does not compile, but this is what I am looking to be able to do
var myFooDTO= new FooDTO<fooDataType>();

我正在寻找什么?对于高使用率代码来说是否太慢(因为使用反射。

5 个答案:

答案 0 :(得分:2)

您可以使用Type.MakeGenericType通过反射执行此操作。

由于反射会产生一些开销,因此您需要对其进行分析,以确定这是否会对您造成影响。

答案 1 :(得分:2)

为什么不使用方法类型推理:

public class FooDTO<TType> {
    public TType Value { get; private set; }
}

public class Foo : FooDTO<ushort> { }

static FooDTO<T> GetTypedFoo<T>(T Obj) {
    return new FooDTO<T>();
}

static void Main(string[] args) {
   Foo F = new Foo();

   var fooDTO = GetTypedFoo(F.Value);
}

答案 2 :(得分:1)

总是当我用一句话读“通用”和“运行时”时,我总是“糟糕的设计”或“不理解通用的意思”。可能两者都有。

通用参数是该类型的组成部分。所以说“在运行时生成通用类型”与“在运行时生成Foo类”相同。您要么寻找反射,要么更改算法的设计。

在这种情况下,var关键字也无法帮助您。算了吧。

答案 3 :(得分:0)

您正在寻找编译时反射,这是C#没有的功能。因此,如果您正在寻找性能优化,那么解决方案会比问题更糟糕。

D确实有此功能;你可以轻松写出

int x = 0;
typeof(x) y = x + 2;

甚至是D中更复杂的表达式,它们都是在编译时进行评估的。

答案 4 :(得分:0)

你想要的核心是:

var type = typeof(FooDTO<>).MakeGenericType(fooDataType);
object obj = Activator.CreateInstance(type);

然而,你会注意到这是反思,并且几乎与object联系在一起。通常的解决方法是访问非通用版本的API,以便您可以使用object - 例如(添加非通用IBar):< / p>

IBar bar = (IBar)Activator.CreateInstance(type);

你当然可以将运行时/泛型命中率提高 - 也许是一个通用方法;然后泛型方法中的所有内容都可以使用T,并且您可以使用MakeGenericMethod在仅在运行时知道的特定T的上下文中执行该方法。