Generate Generic Type At Runtime

♀尐吖头ヾ 提交于 2019-12-11 00:32:39

问题


I am wondering if it is possible to use the type of one variable to set as the type of another generic variable?

For example, say I have this code:

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

    public ushort Value { get; private set; }
}

I also have this class:

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

In these examples, in the interface for IBar has the property

TType Value;

Then in my code I have this

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>();

Is what I am looking for possible? Would it be too slow for high use code (because of using reflection.


回答1:


You can do this via Reflection, by using Type.MakeGenericType.

This will have some overhead due to reflection, so you'd need to profile it to see if that will be an issue for you.




回答2:


Why not use Method type inference:

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);
}



回答3:


Always when I read "generic" and "runtime" in one sentence, I always thing "bad design" or "doesnt understant what generic means". Possibly both.

Generic parameter is integral part of the type. So saying "Generate Generic Type At Runtime" is same as "Generate Foo class at runtime". You are either looking for reflection or change design of your algorithm.

Also var keyword is not going to help you in this case. Forget about it.




回答4:


You're looking for compile-time reflection, a feature that C# doesn't have. So if you're looking for performance optimizations, the solutions are worse than the problem.

D does have this feature, though; you can easily write

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

or even much more complicated expressions in D, and it's all evaluated at compile-time.




回答5:


The core of what you want is:

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

however, you'll notice that this is reflection, and pretty much ties you to object. The usual workaround to this is to have access to a non-generic version of the API, so that you can work with object - for example (with the addition of a non-generic IBar):

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

You can of course move the runtime/generics hit higher up - perhaps into a generic method; then everything in the generic method can use T, and you can use MakeGenericMethod to execute that method in the context of a particular T known only at runtime.



来源:https://stackoverflow.com/questions/5059945/generate-generic-type-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!