我可以覆盖接口属性吗?

时间:2012-06-28 21:17:33

标签: vb.net properties interface override implementation

Shell示例如下。基本上,我希望客户和员工从IPerson实施SSN属性。但是,我希望客户得到并设置(这不是问题),但我希望员工只得到。

Public Interface IPerson
    Property SSN As String
End Interface

Public Class Client
    Implements IPerson
    Public Property SSN As String Implements AELName.IPerson.SSN
        Get
            Return _SSN
        End Get
        Set(value As String)
            _SSN = value
        End Set
    End Property
End Class

Public Class Employee
    Implements IPerson
    Public Readonly Property SSN As String Implements AELName.IPerson.SSN
        Get
            Return _SSN
        End Get
    End Property
End Class

员工生成错误“'SSN'无法实现'SSN',因为接口'IPerson'上没有匹配的属性”。是否有一种简单的方法来覆盖Employee的SSN实现?

3 个答案:

答案 0 :(得分:5)

您可以实现一个空Set - 一个不更新任何内容的文件。

Public Class Employee
    Implements IPerson
    Public Readonly Property SSN As String Implements AELName.IPerson.SSN
        Get
            Return _SSN
        End Get
        Set
            ' Make read only for Employee
        End Set
    End Property
End Class

答案 1 :(得分:2)

我建议将界面拆分为IReadablePerson和IReadWritePerson,后者继承前者。请注意,前一个接口不是IImmutablePerson,因为后一个名称意味着该类的消费者不应期望其任何属性发生变化;一个实现IReadWritePerson的对象不会遵循这样的期望,但会遵守这个人应该可读的期望。

分割界面的一个小麻烦是IReadWritePerson必须在其读/写属性的声明中包含修饰符Shadows,以及IReadWritePerson的实现者必须提供IReadablePerson的只读实现和IReadWritePerson的读写实现。在C#中,读写属性的公共实现可以自动生成任何类似命名的只读,只写或读写属性的实现,这些属性是类实现的任何接口的一部分,但是在明确声明哪个接口时正在实现,接口的样式(只读,只写,读写)必须精确匹配实现的样式。烦。

由于人们不能简单地使用只读属性声明IReadableFoo,使用只写属性声明IWriteOnlyFoo并让IReadWriteFoo简单地继承这两者,这会让烦恼更加严重。如果一个接口实现了一个只读属性和一个具有相同名称的只写属性,那么这两个属性都不可用,因为编译器会在somevariable = object.somePropertysomeObject.someProperty = someVariable这样的语句中宣布它是“模糊的”要使用哪种实现方式。不是我可以看到任何歧义 - 我看不出第一个如何使用除吸气剂之外的任何东西,或后者除了一个setter之外的任何东西,但编译器无法解决它。

答案 2 :(得分:0)

回答标题问题“我可以覆盖接口属性”......绝对可以。以下是如何操作的示例。您只需将可覆盖关键字添加到基础具体实现中。我知道这并不能解决将属性更改为ReadOnly的问题,但我想我会指出覆盖基类的具体实现是可能的。

Module Module1

    Sub Main()

        Dim iEntity As IEntity = New MyEntity

        iEntity.SetMessage(iEntity)

        Console.WriteLine(iEntity.Message)

        Console.ReadKey()

    End Sub

End Module

Public Interface IEntity

    Property Message As String

    Sub SetMessage(entity As IEntity)

End Interface


Public Class MyEntity
    Inherits BaseEntity

    Public Overrides Property Message As String
        Get
            Return String.Format("{0}.. and overroad.", MyBase.Message)
        End Get
        Set(value As String)
            MyBase.Message = value
        End Set
    End Property

    Public Overrides Sub SetMessage(entity As IEntity)

        Me.Message = "I was set from MyEntity."

    End Sub

End Class


Public Class BaseEntity
    Implements IEntity

    Public Overridable Property Message As String Implements IEntity.Message

    Public Overridable Sub SetMessage(entity As IEntity) Implements IEntity.SetMessage
        Me.Message = "I was set from BaseEntity."
    End Sub

End Class