我有一个以下层次结构(为简洁起见,我不在这里写构造函数和类似的项目):
Interface IData
ReadOnly Property ID As Integer
ReadOnly Property Name As String
End Interface
Public Class Data1
Implements IData
ReadOnly Property CoolProperty1 As String
End Class
Public Class Data2
Implements IData
ReadOnly Property CoolProperty2 As String
End Class
现在,WinForms应用程序中的代码是:
Dim a As List(Of IData) = {New Data1(1, "Name1", "Cool1_1"),
New Data1(1, "Name2", "Cool1_2")}.ToList();
someDataGridView.DataSource = a
当我这样做时,我只有列ID和名称。为了查看列CoolProperty1,我必须做显式的Cast:
Sub FillDGV(ByVal lst as List(Of IData)
someDataGridView.DataSource = a.Cast(Of Data1).ToList()
End Sub
如果我考虑了类Data2,则上面的Sub变为:
Sub FillDGV(ByVal lst as List(Of IData)
If Not lst.Any Then Return
If TypeOf lst.First Is Data1 Then
someDataGridView.DataSource = lst.Cast(Of Data1).ToList()
ElseIf TypeOf lst.First Is Data2 Then
someDataGridView.DataSource = lst.Cast(Of Data2).ToList()
Else
someDataGridView.DataSource = lst
EndIf
End Sub
我明白为什么编译器会这样做,但我想知道是否有任何漂亮的模式可以让我避免这样的演员表。
UPDATE:问题是我的FillDGV函数总是收到列表,其中包含相同类型的项目,它是List(Of Data1)或List(Of DATA2)。
解: 看来我有个主意。泛型将在这里提供帮助:
Sub FillDGV(Of T As IData)(ByVal lst as List(Of T))
someDataGridView.DataSource = lst
End Sub
答案 0 :(得分:0)
您需要为每种类型都有一个FillDGV子,或者一个覆盖实现该接口的所有类型的通用子。如果你对每种类型做同样的事情(即,只是将它绑定到网格),那么你可以去通用路线。如果你想对每种类型做一些特定的事情,那么你需要像这样重载FillDGV子:
Sub FillDGV(ByVal lst as List(Of Data1))
If Not lst.Any Then Return
For each item In lst
Console.WriteLine(item.CoolProperty1.ToString())
Next item
someDataGridView.DataSource = lst
End Sub
Sub FillDGV(ByVal lst as List(Of Data2))
If Not lst.Any Then Return
For each item In lst
Console.WriteLine(item.CoolProperty2.ToString())
Next item
someDataGridView.DataSource = lst
End Sub
答案 1 :(得分:0)
(上面的公布答案)。
看来我有个主意。泛型将在这里提供帮助:
Sub FillDGV(Of T As IData)(ByVal lst as List(Of T))
someDataGridView.DataSource = a
End Sub