【发布时间】:2011-01-11 20:35:48
【问题描述】:
为什么一个interface会覆盖一个class定义并违反类封装?我在下面包含了两个示例,一个在 C# 中,一个在 VB.net 中?
VB.net
Module Module1
Sub Main()
Dim testInterface As ITest = New TestMe
Console.WriteLine(testInterface.Testable) ''// Prints False
testInterface.Testable = True ''// Access to Private!!!
Console.WriteLine(testInterface.Testable) ''// Prints True
Dim testClass As TestMe = New TestMe
Console.WriteLine(testClass.Testable) ''// Prints False
''//testClass.Testable = True ''// Compile Error
Console.WriteLine(testClass.Testable) ''// Prints False
End Sub
End Module
Public Class TestMe : Implements ITest
Private m_testable As Boolean = False
Public Property Testable As Boolean Implements ITest.Testable
Get
Return m_testable
End Get
Private Set(ByVal value As Boolean)
m_testable = value
End Set
End Property
End Class
Interface ITest
Property Testable As Boolean
End Interface
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace InterfaceCSTest
{
class Program
{
static void Main(string[] args)
{
ITest testInterface = new TestMe();
Console.WriteLine(testInterface.Testable);
testInterface.Testable = true;
Console.WriteLine(testInterface.Testable);
TestMe testClass = new TestMe();
Console.WriteLine(testClass.Testable);
//testClass.Testable = true;
Console.WriteLine(testClass.Testable);
}
}
class TestMe : ITest
{
private bool m_testable = false;
public bool Testable
{
get
{
return m_testable;
}
private set
{
m_testable = value;
}
}
}
interface ITest
{
bool Testable { get; set; }
}
}
更具体
如何在 VB.net 中实现一个接口,以允许 private setter。例如在 C# 中我可以声明:
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 中将 interface 属性声明为 readonly,我将无法创建 setter。如果我将 VB.net interface 创建为一个普通的旧 property,那么接口声明将违反我的 encapsulation。
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 only Interface 并进行适当的封装?
我认为第一个示例可能是最好的方法。但是,似乎接口定义凌驾于类定义之上。所以我尝试创建一个 getter only (Readonly) property,就像在 C# 中一样,但它不适用于 VB.net。也许这只是语言的限制?
更新
根据 Hans Passant 的评论,我已提交功能请求,发现:https://connect.microsoft.com/VisualStudio/feedback/details/635591/create-a-readonly-interface-that-allows-private-setters-c-to-vb-net-conversion
如果您也想要相同的兼容性功能,请投票!
【问题讨论】:
-
你不能,这是不允许的语法。在 connect.microsoft.com 上发布功能请求,团队将接受任何使两种语言功能具有可比性的请求。现在,您必须使用私有方法来设置支持字段。
-
@Hans Passant。谢谢你。功能请求可以在这里找到:connect.microsoft.com/VisualStudio/feedback/details/635591/…
-
您需要删除 ReadOnly。期间。
-
@AMissico:为什么?现在我刚刚通过接口实例访问了我的私有变量。我觉得 Hans Passant 的回答比较合适。
-
我赞成功能请求,问得好。一票否决,我没有意识到那个连接是stackoverflowian。我第一次看到。