簡體   English   中英

VB.NET 類繼承一個基類並實現一個接口問題(在 C# 中工作)

[英]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您的屬性標記為OverridableMustOverride ,然后您可以在子類中覆蓋它:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM