[英]How can I have a class that implements an interface and inherits from an abstract class? (C# .NET 3.5)
[英]VB.NET class inherits a base class and implements an interface issue (works in C#)
我正在嘗試在 VB.NET 中創建一個類,它繼承了一個基本抽象類並實現了一個接口。 該接口聲明了一個名為 Description 的字符串屬性。 基類包含一個名為 Description 的字符串屬性。 主類繼承基類並實現接口。 基類中描述屬性的存在滿足了接口要求。 這在 C# 中工作正常,但在 VB.NET 中會導致問題。
首先,這是一個有效的 C# 代碼示例:
public interface IFoo
{
string Description { get; set; }
}
public abstract class FooBase
{
public string Description { get; set; }
}
public class MyFoo : FooBase, IFoo
{
}
現在這里是 VB.NET 版本,它給出了一個編譯器錯誤:
Public Interface IFoo
Property Description() As String
End Interface
Public MustInherit Class FooBase
Private _Description As String
Public Property Description() As String
Get
Return _Description
End Get
Set(ByVal value As String)
_Description = value
End Set
End Property
End Class
Public Class MyFoo
Inherits FooBase
Implements IFoo
End Class
如果我讓基類 ( FooBase
) 實現接口並將Implements IFoo.Description
添加到屬性,一切都很好,但我不希望基類實現接口。
編譯器錯誤是:
類“MyFoo”必須為接口“IFoo”實現“Property Description() As String”。 實現屬性必須具有匹配的“ReadOnly”或“WriteOnly”說明符。
VB.NET 不能處理這個問題,還是我需要在某處更改我的語法才能使其正常工作?
您需要在基類MustOverride
您的屬性標記為Overridable
或MustOverride
,然后您可以在子類中覆蓋它:
Public MustInherit Class FooBase
Private _Description As String
Public Overridable Property Description() As String
Get
Return _Description
End Get
Set(ByVal value As String)
_Description = value
End Set
End Property
End Class
Public Class MyFoo
Inherits FooBase
Implements IFoo
Public Overrides Property Description() As String Implements IFoo.Description
Get
Return MyBase.Description
End Get
Set(ByVal value As String)
MyBase.Description = value
End Set
End Property
End Class
編輯這是對@MA Hanin 發布的內容的回應。 我們的兩種解決方案都有效,但了解每種解決方案的后果很重要。 想象一下以下代碼:
Dim X As FooBase = New MyFoo()
Trace.WriteLine(X.Description)
從 X.Description 中得出什么? 使用 Overridable 可以調用子類,而使用 Overload 方法可以調用基類。 沒有對錯,重要的是了解聲明的后果。 使用 Overload 方法,您必須向上轉換才能獲得孩子的實現:
Trace.WriteLine(DirectCast(X, MyFoo).Description)
如果您只是從子類調用 MyBase.Description ,則問題沒有意義,但是如果您更改了子類的定義,那么您只需要確保了解正在發生的事情。
一種或另一種方式,您必須指定 IFoo 接口的實現細節。
這個簡單的選項怎么樣?
Public Class MyFoo
Inherits FooBase
Implements IFoo
Overloads Property Description() As String Implements IFoo.Description
Get
Return MyBase.Description
End Get
Set(ByVal value As String)
MyBase.Description = value
End Set
End Property
End Class
抱歉,如果我遲到了,如果此功能僅在 .NET 4 中引入,我也很抱歉,但以下是可能的(現在)
Public Interface IFoo
Property Description() As String
End Interface
Public MustInherit Class FooBase
Implements IFoo
Public MustOverride Property Description As String Implements IFoo.Description
End Class
Public Class MyFoo
Inherits FooBase
Private _description As String
Public Overrides Property Description As String
Get
Return _description
End Get
Set(value As String)
_description = value
End Set
End Property
End Class
VB 要求實現屬性聲明實現。 這是因為我實際上認為 VB 的一個很好的特性是我有時會在 C# 中錯過——您可以重命名實現接口成員的成員。
因此,在FooBase
不實現IFoo.Description
的唯一方法是聲明Description
Overridable
然后將MyFoo
定義為:
Public Class MyFoo
Inherits FooBase
Implements IFoo
Public Overrides Property Description() As String Implements IFoo.Description
Get
Return MyBase.Description
End Get
Set(ByVal value As String)
MyBase.Description = value
End Set
End Property
End Class
VB.NET 不支持隱式實現。 我也遇到了這個問題,遇到了很多麻煩。
當您使用生成的類(實體等)時,您必須顯式聲明Implements IFoo
,這根本不可能。
因此我向微軟提交了一個連接,我希望你能投票,下一個版本的 VB 他們將改進編譯器,使其更聰明。
由於我的代表,我無法對 MA Hanin 的回答發表評論,但我建議進行一個小調整,以避免編譯器發出有關隱藏基方法的警告,假設您不想或無法覆蓋基類中的屬性。
Public Class MyFoo
Inherits FooBase
Implements IFoo
Private Property IFoo_Description() As String Implements IFoo.Description
Get
Return Me.Description
End Get
Set(ByVal value As String)
Me.Description = value
End Set
End Property
End Class
這是一個奇怪的問題,它清楚地顯示了 C# 和 VB.NET 編譯器之間的差異。 我建議您確實在抽象基類上實現接口,因為這將使 VB.NET 編譯器滿意,並且在執行時您的子類仍將具有元數據,表明它確實實現了IFoo
。
子類必須是聲明它實現接口的那個,是否有特定的原因?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.