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

发布于 2024-09-03 10:44:47 字数 685 浏览 9 评论 0原文

正如标题所示,我试图将变量数据类型传递给模板类。像这样的事情:

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

我假设这与编译时处理的模板有关,但即使我在那里偏离了目标,它也无法解决我的问题。我也找不到任何有关使用反射来实例模板类的相关信息。

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

两个我 2024-09-10 10:44:47

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[]{});

A C# example of something pretty close is located here on a question I had:

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

Converting to VB.NET, changing it to type creation not method invocation and using your example names for you:

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(){})

(Ah for some reason I thought you wanted it in VB.NET but here is a C# example)

LookupForm<Models.MyClass> frmExample;
Type SelectedType = InstanceOfMyClass.GetType();   
Type GenericLookupType = typeof(LookupForm<>).MakeGenericType(SelectedType);
frmExample = Activator.CreateInstance(GenericLookupType, new object[]{});
拥抱没勇气 2024-09-10 10:44:47

使用 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!!!'

Use 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!!!

And VB.NET version :)

    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!!!'
小耗子 2024-09-10 10:44:47

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

This sounds like a candidate for the Dynamic Language Runtime, 'Dynamic' type in C#, but that would require you to use .NET 4.0

断爱 2024-09-10 10:44:47

不幸的是,你不能不反思就做到这一点,即使如此,它也不是很友好。反射代码将如下所示:

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 是动态设置的),但您仍然可以通过反射调用其上的方法,或者您可以创建一个非通用接口将其强制转换为 &调用该方法。

Unfortunately you can't do this without reflection and even then its not very friendly. The reflection code will looks something like this:

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

Of course now you don't know what to cast your object to (assuming selectedType was dynamically set), but you can still call the methods on it via reflection, or you could create a non-generic interface to cast it to & call the methods on that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文