[英].NET: Interface Problem VB.net Getter Only Interface
为什么接口会覆盖类定义并违反类封装? 我在下面提供了两个示例,一个在C#中 ,一个在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
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一个界面 ,将允许私人二传手 。 例如,在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中将接口属性声明为只读 ,则无法创建设置器。 如果我将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中定义具有适当封装的仅吸气剂接口 ?
我认为第一个示例将是最好的方法。 但是,似乎接口定义取代了类定义。 所以我试图像C#中那样创建仅getter(Readonly)属性 ,但不适用于VB.net 。 也许这只是语言的局限性?
根据Hans Passant的评论,我已经提交了发现的功能请求: https : //connect.microsoft.com/VisualStudio/feedback/details/635591/create-a-readonly-interface-that-allows-private-setters-c-to -vb-net转换
如果您也想要相同的兼容性功能,请投票给它!
这是我在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
当接口要求使用只读属性时,您的实现应省略setter。 声明为“只读”的属性不能具有“设置”。
丹回答了您的第二个问题,让我回答您的第一个问题:
为什么接口会覆盖类定义并违反类封装?
这不是特定于属性的。 考虑以下(简单)示例,该示例显示与您的示例相同的行为:
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
,您可以指定如果通过接口I
访问C
类的对象,则调用I.DoSomething
将执行您的私有方法C.DoSomething
(碰巧共享相同的名称,但这只是一个巧合)。 这并不违反封装:通过使用Implements ...
, 您指定希望通过此(公共)接口方法可访问此方法。 因此,基本上,您可以将Implements
关键字视为提供了对该方法(或示例中的属性)的第二种访问方式,它独立于“主要”访问方式的访问修饰符。
因此, DirectCast(myC, I).DoSomething()
可以工作(因为它访问接口方法,碰巧“调用”您的私有方法),但是当在C
之外使用myC.DoSomething()
将无法编译。
在您的示例中发生了同样的事情:在接口obj.Testable = ...
Property Testable As Boolean
指定Property Testable As Boolean
可以确保obj.Testable = ...
可以(公开)在ITest
类型的每个obj
上调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.