将泛型类型T的对象转换为特定类型

时间:2014-11-05 16:18:33

标签: .net vb.net

我已经声明了一个基类(使用CSLA.NET)

Public Class EditableBase(Of T As EditableBase(Of T))
    Inherits BusinessBase(Of T)

End Class

我有我的公司类继承自此基础并被声明为

<Serializable()> _
Public Class Company
    Inherits EditableBase(Of Company)

End Class

现在在我的代码中,我需要检查类型是否为公司类型,我可以这样做

If GetType(T) Is GetType(Company) Then

但是如何将对象转换为此类型?我试过了

Dim lObject As Company = DirectCast(Me, Company)

但是这似乎是错误的消息

  

类型的价值&#39; T&#39;无法转换为公司

2 个答案:

答案 0 :(得分:3)

如果EditableBase班级正在做这样的事情,那么它显然不起作用:

If GetType(T) Is GetType(Company) Then
    Dim o As Company = DirectCast(Me, Company)  ' Fails to compile
End If

你不能这样做,因为Me显然是EditableBase(Of Company)的一个实例。您无法自动从EditableBase(Of T)转换为Company。编译器知道类型,它知道它们不兼容,所以它不允许它。但是,由于您知道,在这种情况下,TCompany,而Company确实从EditableBase(Of Company)继承,您可以通过首先转换为{{}来欺骗它1}}。编译器将始终允许您从Object转换为其他任何内容。

Object

然而,在我看来,所有这些都是设计糟糕的迹象。首先,If GetType(T) Is GetType(Company) Then Dim o As Company = DirectCast(DirectCast(Me, Object), Company) ' Compiles successfully End If 以这种方式受到约束是相当奇怪的。此外,让基类检查派生类的特定具体类型,就像这样,几乎可以肯定它是一种可以更好地设计它的标志。

根据定义,无论派生类的类型如何,基类都应始终以相同的方式运行。如果由于某种原因,它必须,那么继承关系根本不是真的。例如,如果一个名为T的基类具有条件逻辑,当它是Animal时会导致它采取不同的行为,那么你无法在逻辑上说Cat和{{{ 1}}是Cat的类型。这就像说动物是活着的东西,除非它不是,在这种情况下有时也是如此。我认为可以用这种方式定义某些东西,但它变成了一个毫无意义的定义。

类似地,泛型类不应根据其泛型类型参数的类型(即Dog)采取不同的行为。如果由于某种原因,他们必须,那么他们根本不是真正的通用。

答案 1 :(得分:0)

听起来你需要从接口或基类实现,而不是通用(T)。泛型设计应该对不同类型非常开放,而您正在尝试将其限制为类的子集,因此应该使用基类或接口。