Класс VB.NET наследовал базовый класс и реализует интерфейсную проблему (работы в C#)

Я пытаюсь создать класс в VB.NET, который наследовал основной абстрактный класс и также реализует интерфейс. Интерфейс объявляет свойство строки под названием Описание. Базовый класс содержит свойство строки под названием Описание. Основной класс наследовал базовый класс и реализует интерфейс. Существование свойства 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'. Свойство Implementing должно иметь соответствие спецификаторам 'Только для записи' или 'Только для чтения'.

VB.NET VB.NET не может обработать это, или я должен изменить свой синтаксис где-нибудь, чтобы заставить это работать?

32
задан KyleMit 28 January 2015 в 20:21
поделиться

4 ответа

Вам нужно пометить свое свойство как 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 из дочернего класса, вопрос спорный, но если вы когда-нибудь измените определение дочернего класса, вы просто нужно убедиться, что вы понимаете, что происходит.

22
ответ дан 27 November 2019 в 21:02
поделиться

Это странная проблема, и она ясно показывает разницу между компиляторами C # и VB.NET. Я бы посоветовал вам реализовать интерфейс в абстрактном базовом классе, поскольку это сделает компилятор VB.NET счастливым, и во время выполнения ваш дочерний класс все еще будет иметь метаданные, указывающие на то, что он действительно реализует IFoo .

Есть ли конкретная причина, по которой дочерний класс должен объявить, что он реализует интерфейс?

0
ответ дан 27 November 2019 в 21:02
поделиться

Так или иначе, вы должны указать детали реализации интерфейса 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
11
ответ дан 27 November 2019 в 21:02
поделиться

VB требует, чтобы реализующее свойство объявляло реализацию. Это связано с тем, что я считаю хорошей особенностью VB, которой мне иногда не хватает в C# - вы можете переименовать член, реализующий член интерфейса.

Таким образом, единственный способ заставить это работать без реализации IFoo. Description в FooBase, это объявить 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
4
ответ дан 27 November 2019 в 21:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: