.NET泛型类实例 - 传递可变数据类型

时间:2010-06-02 00:52:06

标签: c# vb.net generics reflection dynamic-typing

正如标题所示,我正在将可变数据类型传递给模板类。像这样:

frmExample = New LookupForm(Of Models.MyClass) 'Works fine

Dim SelectedType As Type = InstanceOfMyClass.GetType() 'Works fine
frmExample = New LookupForm(Of SelectedType) 'Ba-bow!
frmExample = New LookupForm(Of InstanceOfMyClass.GetType()) 'Ba-bow!

LookupForm<Models.MyClass> frmExample;
Type SelectedType = InstanceOfMyClass.GetType();
frmExample = new LookupForm<SelectedType.GetType()>(); //Ba-bow
frmExample = new LookupForm<(Type)SelectedType>(); //Ba-bow

我认为它与在编译时处理的模板有关,但即使我在那里没有标记,它也无法解决我的问题。我找不到有关将反射用于实例模板类的任何相关信息。

(如何)我可以在运行时创建动态类型存储库的实例吗?

4 个答案:

答案 0 :(得分:9)

我所遇到的一个问题是here位于非常接近的C#示例:

typeof(MyClass).GetMethod("Foo").MakeGenericMethod(new[] { param.GetType() }).Invoke(null, new[] { param });

转换为VB.NET,将其更改为类型创建而不是方法调用并使用您的示例名称:

Dim frmExample as LookupForm<Models.MyClass>;
Dim SelectedType as Type = InstanceOfMyClass.GetType();   
Dim GenericLookupType as Type = GetType(LookupForm(Of)).MakeGenericType(SelectedType)
frmExample = Activator.CreateInstance(GenericLookupType, new object(){})

(出于某种原因,我认为你想在VB.NET中使用它,但这里是一个C#示例)

LookupForm<Models.MyClass> frmExample;
Type SelectedType = InstanceOfMyClass.GetType();   
Type GenericLookupType = typeof(LookupForm<>).MakeGenericType(SelectedType);
frmExample = Activator.CreateInstance(GenericLookupType, new object[]{});

答案 1 :(得分:6)

使用Type.MakeGenericType

Type modelType = typeof(Models.MyClass);
var repoType = typeof(LookupForm<>).MakeGenericType(new [] {modelType} );
//at this point repoType == typeof(LookupForm<Models.MyClass>);
var repo = Activator.CreateInstance(repoType );
//Ta-dah!!!

和VB.NET版本:))

    Dim modelType As Type = GetType(Models.MyClass)
    Dim repoType As Type = GetType(LookupForm(Of )).MakeGenericType(New Type() {modelType})
    'at this point repoType = GetType(LookupForm(of Models.MyClass))'
    Dim repo = Activator.CreateInstance(repoType)
    'Ta-dah!!!'

答案 2 :(得分:1)

这听起来像是动态语言运行时的候选者,C#中的“动态”类型,但这需要你使用.NET 4.0

答案 3 :(得分:1)

不幸的是,如果没有反思,你就无法做到这一点,即使它不是很友好。反射代码看起来像这样:

Type baseType = typeof(LookupForm<>);
Type selectedType = InstanceOfMyClass.GetType(); //or however else you want to get hold of it
Type genericType = baseType.MakeGenericType(new Type[] { selectedType });
object o = Activator.CreateInstance(genericType);

当然现在你不知道将对象转换为什么(假设selectedType是动态设置的),但你仍然可以通过反射调用它上面的方法,或者你可以创建一个非泛型的接口把它投射到&amp;在那上面调用方法。