Determining a Generic Type at Runtime in Non-Gener

2019-08-14 07:11发布

I've gotten myself in a pickle, and could use the help of a guru...

I have a Journal that records entries for different types:

Journal(Of ParentT)

- Parent could be Customer, Address, other classes

The constructor of the Journal requires knowledge of the Type parameter:

Public Sub New(Parent as ParentT)

In my consuming form, I take a Journal in the constructor:

Public Sub DisplayForm(Journal as object)

At this point, I cannot determine what type the Journal is for. I have looked at using Reflection with the MethodInfo > MakeGenericMethod, DynamicMethod, delegates, etc, but haven't found a workable solution.

I am willing to consider most any option at this point...

2条回答
Anthone
2楼-- · 2019-08-14 07:47

I may have misunderstood the question, but if I understand correctly, Journal is in fact a generic class with generic parameter ParentT; it is only that the reference to a Journal<ParentT> instance is of the non-generic System.Object type. In this case, the following method should work fine:

System.Type.GetGenericArguments

Sorry that this code is in C#, but:

 object obj = new List<int>();
 Console.WriteLine(obj.GetType().GetGenericArguments().First().ToString());

Output:

System.Int32

In your case, you might want something like:

Type journalGenericType = myJournal.GetType().GetGenericArguments().First();

if (journalGenericType == typeof(Customer))
{
    ...
}
else 
{
    ...
}
查看更多
戒情不戒烟
3楼-- · 2019-08-14 07:57

I know I'm a bit late to this party, but I thought I'd weigh in.

There are a number of non-reflection-based approached you could use here.

This DisplayMethod call that you pass the journal to isn't the constructor of your form (otherwise it'd be called New) so I assume that it is a method that figures out which form to load to display the journal.

If so, you could simply add the generic parameter to this method call like so:

Public Sub DisplayForm(Of ParentT)(Journal As Journal(Of ParentT))
   Dim JournalParentType = GetType(ParentT)
   '...
End Sub

Since you're using IoC you could even go one step further. Something like this:

Public Sub DisplayForm(Of ParentT)(Journal As Journal(Of ParentT))
   Dim form = ioc.Resolve(Of IForm(Of ParentT))
   form.DataSource = Journal.Parent
   form.Show()
End Sub

Of course you would need to define your own IForm(Of T) interface to make this work - but now there is no reflection required.

Another approach would be to have a Journal base class of Journal(Of ParentT) and have a ParentType property on Journal. Alternatively you could have an IJournal interface that does the same thing.

查看更多
登录 后发表回答