Tutorial :How to pass a generic type not having a Interface to a Of T function



Question:

I have a following code which works fine

MsgBox(AddSomething(Of String)("Hello", "World"))    Public Function AddSomething(Of T)(ByVal FirstValue As T, ByVal SecondValue As T) As String      Return FirstValue.ToString + SecondValue.ToString  End Function  

Now we are redesigning the application to work with parameters of different types which will be provided through XML

  <SomeValues>      <Add Param1="Somedata" Param2="SomeData" MyType="String"/>      <Add Param1="Somedata" Param2="SomeData" MyType="MyBusinessObject"/>    </SomeValues>  

If I try to provide the following it gives error as Of accepts only type

    ''''Get DetailsFromXml --- MyType,Param1,Param2      MsgBox(AddSomething(Of Type.GetType(MyType))(Param1,Param2))  

How to solve this issue.

Edit

The above example is given to make the question simple. Actual issue is as follows I am using SCSF of P&P. Following is per view code which has to be written for each view

Private Sub tsStudentTableMenuClick()      Dim _StudentTableListView As StudentListView      _StudentTableListView = ShowViewInWorkspace(Of StudentListView)("StudentTable List", WorkspaceNames.RightWorkspace)      _StudentTableListView.Show()  End Sub  

Now I want to show the views dynamically.

 Public Sub ShowModalView(ByVal ViewName As String)          Dim _MasterListView As >>>EmployeeListView<<<<          _MasterListView = ShowViewInWorkspace(Of >>>EmployeeListView<<<)("Employee List", WorkspaceNames.RightWorkspace)          _MasterListView.Show()      End Sub  

So the part shown using the arrows above has to be somehow dynamically provided.


Solution:1

The point of generics is to provide extra information at compile-time. You've only got that information at execution-time.

As you're using VB, you may be able to get away with turning Option Strict off to achieve late binding. I don't know whether you can turn it off for just a small piece of code - that would be the ideal, really.

Otherwise, and if you really can't get the information at compile-time, you'll need to call it with reflection - fetch the generic "blueprint" of the method, call MethodInfo.MakeGenericMethod and then invoke it.

I assume that the real method is somewhat more complicated? After all, you can call ToString() on anything...

(It's possible that with .NET 4.0 you'll have more options. You could certainly use dynamic in C# 4.0, and I believe that VB10 will provide the same sort of functionality.)


Solution:2

In .Net generics, you must be able to resolve to a specific type at compile time, so that it can generate appropriate code. Any time you're using reflection, you're resolving the type at run time.

In this case, you're always just calling the .ToString() method. If that's really all your code does, you could just change the parameter type to Object rather than use a generic method. If it's a little more complicated, you could also try requiring your parameters to implement some common interface that you will define.


Solution:3

If all you are doing is ToString, then making the parameters object instead would solve the problem in the simplest way. Otherwise you are going to have to bind the type at run-time, which in C# looks like:

System.Reflection.MethodInfo mi = GetType().GetMethod("AddSomething");  mi = mi.MakeGenericMethod(Type.GetType(MyType));  object result = mi.Invoke(this, new object[] { Param1, Param2 });  

Because it involves reflection it won't be fast though... but I assume that's not a problem in this context.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »