C# .NET:接口问题VB.NET Getter Only接口
为什么接口会覆盖类定义并违反类封装?我在下面包含了两个示例,一个在C#中,另一个在VB.net中 图书管理系统 C# 更具体地说 如何在VB.net中实现一个允许私有setter的接口。例如,在C#中,我可以声明:C# .NET:接口问题VB.NET Getter Only接口,c#,.net,vb.net,C#,.net,Vb.net,为什么接口会覆盖类定义并违反类封装?我在下面包含了两个示例,一个在C#中,另一个在VB.net中 图书管理系统 C# 更具体地说 如何在VB.net中实现一个允许私有setter的接口。例如,在C#中,我可以声明: class TestMe : ITest { private bool m_testable = false; public bool Testable { get { return m_testable
class TestMe : ITest
{
private bool m_testable = false;
public bool Testable
{
get
{
return m_testable;
}
private set //No Compile Error here!
{
m_testable = value;
}
}
}
interface ITest
{
bool Testable { get; }
}
但是,如果在VB.net中将接口属性声明为只读,则无法创建setter。如果我创建一个VB.net接口作为一个普通的旧属性,那么接口声明将违反我的封装
Public Class TestMe : Implements ITest
Private m_testable As Boolean = False
Public ReadOnly Property Testable As Boolean Implements ITest.Testable
Get
Return m_testable
End Get
Private Set(ByVal value As Boolean) ''//Compile Error
m_testable = value
End Set
End Property
End Class
Interface ITest
ReadOnly Property Testable As Boolean
End Interface
因此,我的问题是,如何在VB.net中定义一个具有适当封装的只支持getter的接口
我认为第一个例子是最好的方法。然而,似乎接口定义否决了类定义。因此,我尝试创建一个类似于C#的getter-only(Readonly)属性,但它不适用于VB.net。也许这只是语言的局限
更新
根据Hans Passant的评论,我提交了一个功能请求,发现:
如果您还想要相同的兼容性功能,请投赞成票 当接口调用只读属性时,您的实现应该省略setter。声明为“只读”的属性不能有“集”。以下是我在VB.NET中的操作方法:
Public Interface ITest
ReadOnly Property Testable As Boolean
End Interface
Public Class Test
Implements ITest
' Note: Here I am NOT implementing the interface. '
Private _testable As Boolean
Public Property Testable() As Boolean
Get
Return _testable
End Get
Private Set(ByVal value As Boolean)
_testable = value
End Set
End Property
' This is where I define a read-only property to satisfy the interface '
' (from the perspective of the VB compiler). '
' Notice this is a lot like explicit interface implementation in C#. '
Private ReadOnly Property TestableExplicit() As Boolean Implements ITest.Testable
Get
Return Testable
End Get
End Property
End Class
丹回答了你的第二个问题,让我回答你的第一个问题: 为什么接口会重写类定义并违反类封装 这不是特定于属性的。考虑下面的(简单的)示例,它显示与您的示例相同的行为:
Interface I
Sub DoSomething()
End Interface
这是什么意思?这意味着,如果您有一个类型为i
的对象i
,则始终可以公开调用i.DoSomething()
Public Class C
Implements I
Private Sub DoSomething() Implements I.DoSomething
...
End Sub
End Class
通过使用Implements I.DoSomething
,您可以指定,如果类C
的对象通过接口I
访问,调用I.DoSomething
将执行您的私有方法C.DoSomething
(碰巧共享相同的名称,但这只是巧合)。这并不违反封装:通过使用实现…
,您可以指定希望通过此(公共)接口方法访问此方法。因此,基本上,您可以认为Implements
关键字提供了访问此方法(或属性,在您的示例中)的第二种方式,它独立于“主要”访问方式的访问修饰符
因此,DirectCast(myC,I).DoSomething()
可以工作(因为它访问接口方法,而接口方法恰好“调用”了您的私有方法),但是myC.DoSomething()
在C
之外使用时不会编译
在您的示例中也发生了同样的情况:在接口中指定
属性Testable为Boolean
可以保证obj.Testable=…
可以(公开)调用obj
类型ITest
的每个对象(只读属性Testable为Boolean)!=(bool可测试{get;})。我想知道如何在VB.net中实现类似的功能。请注意,这与其说是语言限制,不如说是语法上的差异。ReadOnly关键字是VB.NET对私有setter的回答。你不能,这是不允许的语法。在connect.microsoft.com上发布功能请求,团队会接受任何使两种语言功能具有可比性的请求。现在,您必须使用私有方法来设置支持字段。@Hans Passant。非常感谢。功能请求可在此处找到:您需要删除只读。句号。@AMissico:为什么?现在,我刚刚通过接口实例访问了我的私有变量。我认为汉斯·帕桑的回答更合适。我对功能要求投了更高的票,问得好。一票否决,我没意识到那个连接是StackOverflovian。我第一次看到这个,谢谢。我一直想知道为什么VB.net必须明确地说明它的实现。这是有道理的。@user295190在我看来,与其说是“必须”,不如说是“到达”。在接口实现的命名和可见性方面,VB比C更具灵活性。感谢您的澄清。
Interface I
Sub DoSomething()
End Interface
Public Class C
Implements I
Private Sub DoSomething() Implements I.DoSomething
...
End Sub
End Class