关于c#:受保护在VB.Net中设置接口中定义的属性

Protected Set in VB.Net for a property defined in an interface

我们有一个接口,可以大致简化为:

1
2
3
4
public interface IPersistable<T>
{
    T Id { get; }
}

大多数实现接口的地方都希望拥有它,以便在该属性上有一个受保护的或私有的集,即在C:

1
2
3
4
public class Foo : IPersistable<int>
{
    public int Id { get; protected set; }
}

但是,我无法获取任何样本vb.net代码来编译遵循相同模式的代码,同时仍在实现接口,因此:

1
2
3
4
5
6
7
8
9
10
11
12
Public Class Foo
    Implements IPersistable(Of Integer)

    Public Property Id() As Integer Implements IPersistable(Of Integer).Id
        Get
            Throw New NotImplementedException()
        End Get
        Protected Set(ByVal value As Integer)
            Throw New NotImplementedException()
        End Set
    End Property
End Class

…不会编译,但这将:

1
2
3
4
5
6
7
8
9
10
Public Class Foo
    Public Property Id() As Integer
        Get
            Throw New NotImplementedException()
        End Get
        Protected Set(ByVal value As Integer)
            Throw New NotImplementedException()
        End Set
    End Property
End Class

我很感激这个例子过于琐碎,并且可能通过受保护的构造函数更好地实现,但是如果可以这样做,我会感兴趣吗?

[编辑:]…显然,如果一个类型想要使用XML序列化,那么属性将需要是公共的读/写,或者类型将需要为每个属性编写自定义序列化程序。

本质上,我认为接口应该定义最小的可访问性,但vb将其解释为精确的可访问性?


是的,您必须从字面上实现接口。可能的解决方法是用另一个名称重新发布类中的属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Public Class Foo
  Implements IPersistable(Of Integer)
  Private m_Id As Integer

  Public ReadOnly Property Id() As Integer Implements IPersistable(Of Integer).Id
    Get
      Return m_Id
    End Get
  End Property

  Protected Property IdInternal() As Integer
    Get
      Return m_Id
    End Get
    Set(ByVal value As Integer)
      m_Id = value
    End Set
  End Property
End Class

如果要在派生类中重写属性,请声明该属性可重写。


从readonly interface properties">Visual Basic 14开始,您的第一个VB代码示例编译得很好。


该语言目前不支持它,在VisualBasic10中也不支持它(即,使用Visual Studio 2010的版本)。这正是一个愿望清单项目。在此之前,Nobugz建议的解决方法是唯一的选择。


接口属性只能由匹配的类属性实现。这在vb.net和c中都是正确的。这两种语言的不同之处在于,C的隐式接口实现功能将自动定义只读或只写属性,以便在具有相同名称的公共读写属性的情况下实现接口。