Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET:接口问题VB.NET Getter Only接口_C#_.net_Vb.net - Fatal编程技术网

C# .NET:接口问题VB.NET Getter Only接口

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

为什么接口会覆盖定义并违反类封装?我在下面包含了两个示例,一个在C#中,另一个在VB.net中

图书管理系统 C# 更具体地说 如何在VB.net中实现一个允许私有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中将接口属性声明为只读,则无法创建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