【问题标题】:If an interface defines a ReadOnly Property, how can an implementer provide the Setter to this property?如果接口定义了 ReadOnly 属性,实现者如何为该属性提供 Setter?
【发布时间】:2011-06-10 13:55:44
【问题描述】:

接口的实现者有没有办法定义ReadOnly 属性使其成为完整的读/写Property

假设我定义了一个接口来提供ReadOnly Property(即,只是一个给定值的getter):

Interface SomeInterface

    'the interface only say that implementers must provide a value for reading
    ReadOnly Property PublicProperty As String

End Interface

这意味着实施者必须承诺提供价值。但我希望给定的实施者也允许设置该值。在我看来,这意味着提供Property 的setter 作为实现的一部分,做这样的事情:

Public Property PublicProperty As String Implements SomeInterface.PublicProperty
    Get
        Return _myProperty
    End Get
    Set(ByVal value As String)
        _myProperty = value
    End Set
End Property

但这不会编译,因为对于 VB 编译器,实现者不再实现接口(因为它不再是 ReadOnly)。

从概念上讲,这应该可行,因为最后,它只是意味着从接口实现 getter,并添加一个 setter 方法。对于“普通方法”来说,这是没有问题的。

有没有办法做到这一点,而不诉诸“界面隐藏”或“自制”SetProperty() 方法,并且具有Property 的样式在实现中表现得像读/写属性?

谢谢!

--更新-- (我已将这个问题 to a separate Question 移动) 我的问题真的是:“为什么不能在 VB.NET 中完成”,当以下内容在 C#.NET 中有效时?”

interface IPublicProperty
{
    string PublicProperty { get; }
}

实施:

public class Implementer:IPublicProperty
    {
        private string _publicProperty;

        public string PublicProperty
        {
            get
            {
                return _publicProperty;
            }
            set
            {
                _publicProperty = value;
            }
        }
    }

【问题讨论】:

  • 更新是个好问题,但我无法回答,我更喜欢 c# 实现。
  • 我想我会在一个单独的问题中发布它。还是谢谢!

标签: vb.net


【解决方案1】:

现在在 Visual Studio 2015 中受支持。

What's New for Visual Basic

只读接口属性

您可以使用读写属性实现只读接口属性。该接口保证了最低限度的功能,并且它不会阻止实现类允许设置属性。

【讨论】:

【解决方案2】:

最后,我得到了一个符合我目标的解决方案:

  • 通过接口访问的用户至少看到一个 getter
  • 访问实施的用户可以读写。

我这样做 “遮蔽”了已实现的属性,如下所示:

'users who access through interface see only the Read accessor
Public ReadOnly Property PublicProperty_SomeInterface As String Implements SomeInterface.PublicProperty
    Get
        Return _myProperty
    End Get
End Property


'users who work with the implementation have Read/Write access
Public Property PublicProperty_SomeInterface As String
    Get
        Return _myProperty
    End Get
    Set(ByVal value As String)
        _myProperty = value
    End Set
End Property

然后,根据你的使用方式,你可以这样做:

Dim implementorAsInterface As SomeInterface = New InterfaceImplementor()
logger.Log(implementor.PublicProperty) 'read access is always ok
implementor.PublicProperty = "toto" 'compile error : readOnly access

Dim implementor As InterfaceImplementor = New InterfaceImplementor()
implementor.PublicProperty = "toto" 'write access

【讨论】:

  • 这本质上是一种“其他方法”方法,PublicProperty 无法从界面访问。您可以通过从PublicProperty getter 调用PublicProperty_FromInterface getter 来实现一些“阴影”。另外,您可以将 PublicProperty_FromInterface 重命名为 PublicProperty_SomeInterface,以防万一您实现的另一个接口也需要 PublicProperty 定义。
  • 我得到“'Public ReadOnly Property Name As String' 和 'Public Property Name As String' 不能相互重载,因为它们的区别仅在于 'ReadOnly' 或 'WriteOnly'”。我不明白你是怎么做到的。
  • @MichalB。它不像写的那样工作。您需要将 ReadOnly 属性的名称更改为对您有意义的另一个名称。您还应该将其设为私有,以免混淆实现类的公共 API。它仍然可以通过接口调用,即使它在实现类中是私有的。
【解决方案3】:

在 CLI 级别没有什么可以阻止这种类型的实现,正如您所展示的那样,C# 已经支持它。 VB.Net 语言就是不支持这种实现方式。

知道原因有点困难,因为此时该决定已经过去了将近 10 年。在设计接口实现时,它很可能只是一个过度站点。

【讨论】:

    【解决方案4】:

    您不能这样做,因为接口要求您实现 ReadOnly 属性。

    属性不允许重载,因此无法实现非只读和只读。

    我建议您实现自定义设置器或从接口中删除 ReadOnly。

    如果没有详细说明您为什么要这样做,就很难提出最佳解决方案

    【讨论】:

    • 我知道如果接口说“ReadOnly”那么实现者应该是“ReadOnly”......但它也可以理解为:“实现者必须至少提供对该属性的读取访问权限” .我最终“隐藏”了实现的方法(见我的回答)
    【解决方案5】:

    在 Visual Basic 中,当您从接口实现方法或属性时,您可以更改其名称和可见性。您可以利用该功能来处理您询问的案例。在 Visual Studio 2015 之前,我经常这样做:

    接口:

    Public Interface SomeInterface
        ReadOnly Property SomeProperty As String
    End Interface
    

    实现类:

    Public Class SomeClass
        Implements SomeInterface
    
        Public Property SomeProperty As String
        Private ReadOnly Property SomeProperty_ReadOnly As String Implements SomeInterface.SomeProperty
            Get
                Return Me.SomeProperty
            End Get
        End Property
    End Class
    

    结果是SomeProperty通过SomeInterface访问时为只读,而通过SomeClass访问时为读写:

    Dim c As New SomeClass
    c.SomeProperty = "hello" 'Write via class OK
    Dim s1 = c.SomeProperty 'Read via class OK
    
    Dim i As SomeInterface = c
    Dim s2 = i.SomeProperty 'Read via interface OK
    i.SomeProperty = "greetings" 'Syntax Error, interface property is read-only
    

    【讨论】:

      猜你喜欢
      • 2020-03-31
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      • 2010-12-08
      相关资源
      最近更新 更多