繁体   English   中英

.NET:界面问题VB.net Getter Only界面

[英].NET: Interface Problem VB.net Getter Only Interface

为什么接口会覆盖定义并违反类封装? 我在下面提供了两个示例,一个在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一个界面 ,将允许私人二传手 例如,在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM