例如,我想接受一个通用的元素列表作为方法参数,并根据构成列表的对象类型执行不同的操作。例如:
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)
,看看它的TypeOf
是List(Of SubClass)
,但是它表示List(Of ParentClass)
永远不能是List(Of SubClass)
类型这似乎没有意义。
答案 0 :(得分:6)
如果需要检查泛型参数以确定代码路径,那么您的方法不是真正的通用,并且应该使用重载方法来处理这种情况:
Private Sub DoStuff(ByRef list as List(Of String))
Private Sub DoStuff(ByRef list as List(Of Integer))
使用ParentClass
和SubClass
时同样有效 - 将调用最具体的重载。
如果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)
被视为完全不同的类型,无论X
和Y
可能共享的关系如何。换句话说,它基本上是创建新类型的简写,如下所示:
Public Class ListOfSubClass
Inherits List(Of SubClass)
End Class
Public Class ListOfParentClass
Inherits List(Of ParentClass)
End Class
如果您这样做,则不希望ListOfParentClass
与ListOfSubClass
兼容,因为它们彼此之间没有任何关系。同样,你不应该期望泛型也能以这种方式工作。
修改强>
虽然我所说的关于同一类通用类的不同类型之间的转换不兼容性是真实的,但它不再是整个故事。从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
}
}