2010-08-14 113 views
1

我已经得到了自己处于困境之中,并且可以使用一个大师的帮助...在非通用类在运行时确定泛型类型

我有日记,记录条目不同的类型:

Journal(Of ParentT) 

- 家长可以CustomerAddress,其他类

期刊的构造函数需要的类型参数的知识:

Public Sub New(Parent as ParentT) 

在我的消费形式,我把日记在构造函数:

Public Sub DisplayForm(Journal as object) 

在这一点上,我不能确定是什么类型的杂志是。我看过使用反射与MethodInfo>MakeGenericMethod,DynamicMethod,代表等,但没有找到一个可行的解决方案。

我愿意在这一点上考虑得最多的任何选项...

回答

1

我可能误解了这个问题,但如果我理解正确的话,Journal实际上是在与通用参数ParentT一个泛型类;只有对Journal<ParentT>实例的引用属于非通用的System.Object类型。在这种情况下,下面的方法应该很好地工作:

System.Type.GetGenericArguments

对不起,该代码是C#,而是:

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

输出:

System.Int32 

在你的情况,你可能想要像这样的东西:

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

if (journalGenericType == typeof(Customer)) 
{ 
    ... 
} 
else 
{ 
    ... 
} 
+0

哇 - 我花了数小时寻找这个!谢谢。 – grefly 2010-08-14 06:17:26

+0

@grefly:太好了。你确定你不能改变设计,不需要反思吗? – Ani 2010-08-14 16:04:01

+0

我必须根据日志类型在IoC中作出决定 - (我没有*赞成约定而不是配置!) - 那么设计更改会是什么样子?我愿意接受建议/推荐意见... – grefly 2010-08-16 02:26:06

0

我知道我对这次派对有点迟,但是我认为我的体重会增加。

有很多非反射的方法可以在这里使用。

这个DisplayMethod调用你通过日志到不是你的窗体的构造函数(否则它会被称为New),所以我认为这是一个方法,计算出哪种形式加载显示日记。

如果是这样,你可以简单地泛型参数添加到这个方法调用就像这样:

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

由于您使用的IoC你甚至可以更进一步。事情是这样的:

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 

当然,你需要定义自己的IForm(Of T)接口,使这项工作 - 但现在还没有需要反思。

另一种方法是让Journal的基类为Journal(Of ParentT),并在日记上拥有ParentType属性。或者,你可以有一个IJournal接口来做同样的事情。