使用接口时避免显式转换

时间:2013-06-17 07:42:40

标签: .net vb.net winforms design-patterns

我有一个以下层次结构(为简洁起见,我不在这里写构造函数和类似的项目):

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

2 个答案:

答案 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