2

外壳示例如下。基本上,我希望客户和员工实现 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 实现?

4

3 回答 3

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
于 2012-06-28T21:19:34.793 回答
2

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

拆分接口的一个小烦恼是,有必要在其读/写属性的声明中IReadWritePerson包含修饰符Shadows,并且实现者IReadWritePerson必须提供只读实现IReadablePerson和读写实现IReadWritePerson. 在 C# 中,读写属性的公共实现可以自动为任何类似命名的只读、只写或读写属性生成实现,这些属性是该类实现的任何接口的一部分,但在显式声明哪个接口时正在实现,接口的样式(只读、只写、读写)必须与实现的样式精确匹配。恼人的。

由于不能简单地IReadableFoo用只读属性IWriteOnlyFoo和只写属性声明并IReadWriteFoo简单地继承两者,这一事实使烦恼变得更糟。如果接口实现了同名的只读属性和只写属性,则这两个属性都将不可用,因为编译器将在somevariable = object.somePropertyor之类的语句中声明someObject.someProperty = someVariable,使用哪个实现是“不明确的”。并不是说我能看到任何歧义——我看不出第一个如何使用除了 getter 之外的任何东西,或者后者除了 setter 之外的任何东西,但编译器无法解决它。

于 2012-06-28T22:21:09.140 回答
0

要回答您的标题问题“我可以覆盖接口属性”......绝对。这是一个如何执行此操作的示例。您只需将Overridable关键字添加到您的基本具体实现。我知道这并不能解决将属性更改为 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
于 2013-10-11T04:12:36.793 回答