如何在方法中检查通用对象的类型?

时间:2013-05-15 16:23:49

标签: .net vb.net

例如,我想接受一个通用的元素列表作为方法参数,并根据构成列表的对象类型执行不同的操作。例如:

Private Sub DoStuff(Of T)(ByRef list As List(Of T) 
    If list.GetType() Is TypeOf(List(Of String) Then
        'Do some string stuff
    Else If list.GetType() Is TypeOf(List(Of Integer) Then  
        'Do some Integer stuff
    End If
End Sub

如果有办法只看到T的类型,那也行。我还试图将我的论点设置为List(Of ParentClass),看看它的TypeOfList(Of SubClass),但是它表示List(Of ParentClass)永远不能是List(Of SubClass)类型这似乎没有意义。

3 个答案:

答案 0 :(得分:6)

如果需要检查泛型参数以确定代码路径,那么您的方法不是真正的通用,并且应该使用重载方法来处理这种情况:

Private Sub DoStuff(ByRef list as List(Of String))
Private Sub DoStuff(ByRef list as List(Of Integer))

使用ParentClassSubClass时同样有效 - 将调用最具体的重载。

如果DoStuff的共享方面确实是通用的,请将它们提取到另一个辅助方法中。

也就是说,您可以使用T检查GetType(T)的类型。

答案 1 :(得分:5)

您可以比较通用类型T,如下所示:

Private Sub DoStuff(Of T)(ByRef list As List(Of T))
    If GetType(T) = GetType(String) Then
        'Do some string stuff
    Else GetType(T) = GetType(Integer) Then  
        'Do some Integer stuff
    End If
End Sub

或者,您甚至可以将其作为Select块执行:

Private Sub DoStuff(Of T)(ByRef list As List(Of T))
    Select GetType(T) 
        Case GetType(String)
            'Do some string stuff
        Case GetType(Integer)
            'Do some Integer stuff
    End Select
End Sub

毋庸置疑,但我想我应该补充一点,如果可能的话,应该不鼓励并避免检查类型。做这样的事情会导致混乱的意大利面条代码,它会破坏使用通用参数的整个目的。通常,当你开始需要做这样的事情时,这是一个很好的迹象,表明你做得很差,你需要重新考虑你的设计。

List(Of ParentClass)List(Of SubClass)不匹配而言,这是人们对仿制药的常见混淆。泛型的工作方式是,可以为泛型类型参数提供的每种可能类型将被视为完全独立的数据类型,与任何其他数据类型完全无关。因此,List(Of X)List(Of Y)被视为完全不同的类型,无论XY可能共享的关系如何。换句话说,它基本上是创建新类型的简写,如下所示:

Public Class ListOfSubClass
    Inherits List(Of SubClass)
End Class

Public Class ListOfParentClass
    Inherits List(Of ParentClass)
End Class

如果您这样做,则不希望ListOfParentClassListOfSubClass兼容,因为它们彼此之间没有任何关系。同样,你不应该期望泛型也能以这种方式工作。

修改

虽然我所说的关于同一类通用类的不同类型之间的转换不兼容性是真实的,但它不再是整个故事。从visual studio 2010和4.0版本的框架开始,.NET支持协方差和逆变,这有助于解决这个问题。有关详细信息,请参阅MSDN article

答案 2 :(得分:0)

您是否可以为每种类型的通用列表创建一个具有相同名称的扩展方法?

在C#中的内容如下:

var listOfStrings = new List<string>();
listOfStrings.DoStuff() //the extension method

var listOfInts = new List<int>();
listOfInts.DoStuff() //the extension method

扩展方法类似于:

public static class listExtensions
{
   public static void DoStuff(this IList<string> theList)
   {
       // Stuff with strings
   }
   public static void DoStuff(this IList<int> theList)
   {
       // Stuff with ints
   }
}