.NET generic instance instance - passing the data type of a variable

As the name suggests, I am tyring to pass a data type variable to a template class. Something like that:

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 assume that this is due to the fact that the template being processed is processed at compile time, but even if I am not familiar with this, it still will not solve my problem. I also cannot find relevant information on using Reflection template classes for instances.

(How) can I instantiate a dynamically typed repository at runtime?

+4
source share
4 answers

An 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 create a type without calling a method and using your 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 an example of C #)

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

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 the version of 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!!!' 
+6
source

It sounds like a candidate for the dynamic Runtime language, type “Dynamic” in C #, but this will require using .NET 4.0

+1
source

Unfortunately, you cannot do this without reflection, and even then it is not very friendly. The reflection code will look 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 do with your object (provided that selectedType been dynamically set), but you can still call methods on it using reflection, or you can create a non-generic interface to create this and call methods On this.

+1
source

Source: https://habr.com/ru/post/1311572/


All Articles