2009-11-17 108 views
1

我有幾個小類來表示搜索過濾器中的部分。如果搜索值等於NonValue,則過濾器應該不做任何事情。這是在一個基類定義:然後多態性和陰影繼承成員

Private Class BaseFilter 
     Protected NonValue As Object 
     Protected sQueryStringBase As String = "AND {0} {1} {2} " 

     Public Sub CheckNonValue(ByVal QueryItem As Object) 
      'No Query if Item not valid 
      If Me.NonValue.Equals(Me.QueryItem) Then 
       Me.sQueryStringBase = String.Empty 
      End If 
     End Sub 

    End Class 

BaseFilter伸出供不同類型的字段:

Private Class StringFilter 
     Inherits BaseFilter 
     Protected Shadows NonValue As String = String.Empty 
    End Class 

當我然後創建StringFilter並檢查允許值:

Dim stf As New StringFilter() 
stf.CheckNonValue(MyString) 

當我期望NonValue對象是String.Empty時,我得到一個NullReferenceException (NonValue = Nothing)。這是我的代碼中的錯誤,還是我試圖以錯誤的方式實現多態?謝謝。

回答

0

讓子類通過構造函數將NonValue對象傳遞給它的基礎。

+0

這就是我最終做的。但是基類似乎仍然用Object.Equals()來檢驗Equal(),它檢查內存地址。因此,我必須重寫子類中的CheckNonValue()方法,並在測試之前將我的NonValue轉換爲所需的類型CType(Me.NonValue, String)。 – Jonas 2009-11-20 14:25:31

0

陰影是你想要的相反...在Visual Basic中的陰影將允許兩個變量被命名爲相同的東西,但不是指同一個對象(即簽名是相同的,但它意味着不同的東西) 。

例如,當您有本地定義的變量foo和類級別變量foo時,會自動發生這種情況。在本地範圍內對foo的任何調用都將訪問本地變量,並且在範圍之外它將訪問類級變量。

+0

@Andrew:有更多的類繼承自BaseFilter,它的想法是能夠在繼承類中重用CheckNonValue方法,因爲無論如何,這個想法是一樣的。 – Jonas 2009-11-17 15:26:26

+0

是的,但我認爲這不能用陰影來實現 - 你想使用像Serilla推薦的東西。 – 2009-11-17 16:56:30

+0

你在影子的正確位置,這真的是壓倒性的我正在尋找。 – Jonas 2009-11-20 14:22:19

1

我認爲你正在努力實現可以通過在BaseFilter NonValue 可覆蓋,然後在派生類中做什麼...

Private Class StringFilter 
    Inherits BaseFilter 
    Protected Overrides NonValue As String = String.Empty 
End Class 

編輯:

正如你正確地指出你不能重寫一個成員變量。另外,你不能用另一種類型覆蓋一種類型;所以即使你已經將你的成員變量改爲屬性,我原來的建議(上面)也不會起作用。爲了贖回我的罪孽:)我已經放在一起,使用仿製藥的另一個建議:

Public MustInherit Class Filter(Of T) 

    Protected NullValue As T 
    Protected QueryStringBase As String = "AND {0} {1} {2} " 

    Public Sub CheckNonValue(ByVal value As T) 
     If NullValue.Equals(value) Then 
      Me.QueryStringBase = String.Empty 
     End If 
    End Sub 

End Class 

Public Class StringFilter 
    Inherits Filter(Of String) 
    Public Sub New() 
     NullValue = String.Empty 
    End Sub 
End Class 

Public Class ObjectFilter 
    Inherits Filter(Of Object) 
    Public Sub New() 
     NullValue = Nothing 
    End Sub 
End Class 
+0

我無法將成員設置爲Overridable(至少在.NET 2.0中,應該也許已經提到過)。 – Jonas 2009-11-20 14:21:01

+0

的確,您無法重寫成員變量。在大多數情況下,你會使用屬性,但在你的情況下,我不得不編輯我的原始答案,以提供一個完全不同的解決方案。 – JulianM 2009-11-21 02:52:19