4

As the title suggests, I'm tyring to pass a variable data type to a template class. Something like this:

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

I'm assuming it's something to do with the template being processed at compile time but even if I'm off the mark there, it wouldn't solve my problem anyway. I can't find any relevant information on using Reflection to instance template classes either.

(How) can I create an instance of a dynamically typed repository at runtime?

4

4 回答 4

9

非常接近的 AC# 示例位于我遇到的一个问题上:

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[]{});
于 2010-06-02T01:33:18.030 回答
7

使用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!!!'
于 2010-06-02T01:29:16.073 回答
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是动态设置的),但是您仍然可以通过反射调用其上的方法,或者您可以创建一个非泛型接口将其转换为并调用方法在那。

于 2010-06-02T01:37:32.030 回答
1

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

于 2010-06-02T01:20:45.883 回答