接口行为在VB.Net中是不同的

时间:2013-09-18 17:59:49

标签: vb.net

接口在Vb.Net中的行为不同。下面是一个示例代码段,其中IStudent接口的方法SayHello由类Student实现。默认情况下,SayHello的访问修饰符应为Public。通过将访问修饰符更改为Private并未破坏现有代码,我仍然可以使用以下代码访问此私有方法

Dim stdnt As IStudent = New Student
stdnt.SayHello()

Access修饰符确定类中成员的范围,更多的私有成员只能从存在的类中访问。但是这里的Access Modifier理论,Encapsulation被打破了。

  • 为什么.net以这种方式设计?
  • Access修饰符和封装的概念真的被打破了吗?
  • .net框架如何内部处理这种情况?

提前致谢

Module Module1

   Sub Main()
        Dim stdnt As IStudent = New Student
        stdnt.Name = "vimal"
        stdnt.SayHello()
   End Sub

End Module

Public Interface IStudent

   Property Name As String

   Sub SayHello()

End Interface

Public Class Student
   Implements IStudent

   Private Property Name As String Implements IStudent.Name

   Private Sub SayHello() Implements IStudent.SayHello
       Console.WriteLine("Say Hello!")
   End Sub

End Class

5 个答案:

答案 0 :(得分:4)

来自MSDN

  

您可以使用私有成员来实现接口成员。当私有成员实现接口的成员时,该成员通过接口变为可用,即使它不能直接在该类的对象变量上使用。

在C#中,通过显式实现接口来实现此行为,如下所示:

public interface IStudent {
    string Name { get; set; }
    void SayHello();
}

public class Student : IStudent {
    string IStudent.Name { get; set; }

    void IStudent.SayHello() {
        Console.WriteLine("Say Hello!");
    }
}

因此,如果你在方法名称前面省略IStudent.,它就会破坏。我看到在VB语法中包含了接口名称。我不知道这是否有任何影响。但是接口成员不是私有的,因为接口不是。他们有点公开......

答案 1 :(得分:4)

原版海报通过TheBugGuys@Coverity.com向我提交了这个问题;我的答案在这里:

https://communities.coverity.com/blogs/development-testing-blog/2013/10/09/oct-9-posting-interface-behaves-differently-in-visual-basic

简要总结一下:

  

为什么.NET以这种方式设计?

这个问题不可能含糊不清。

  

C#和VB中的显式实现是否破坏了封装?

没有。该方法的隐私限制了方法 name 的可访问域,而不是谁可以调用该方法。如果该类的作者选择通过某种机制调用私有方法,而不是通过名称查找,那么这就是他们的选择。第三方不能做出选择,除非通过私人反射等技术打破封装。

  

如何在.NET中实现此功能?

显式接口实现有一个特殊的元数据表。当试图找出哪种类(或结构)方法与哪种接口方法相关时,CLR首先会参考它。

答案 2 :(得分:3)

C#和VB.NET之间没有根本区别,他们只是选择了不同的方法来解决歧义。最好用C#片段演示:

interface ICowboy {
    void Draw();
}
interface IPainter {
    void Draw();
}

class CowboyPainter : ICowboy, IPainter {
    void ICowboy.Draw() { useGun(); }
    void IPainter.Draw() { useBrush(); }
    // etc...
}

VB.NET只选择了一致的接口实现语法,因此程序员不必权衡隐式和显式实现语法之间的差异。只需在VB.NET中明确显示。

只有界面方法的可访问性才重要。永远公开。

答案 3 :(得分:2)

当您的变量stdnt声明为IStudent时,接口方法和属性将被设为Public,因此派生类'执行(学生)实施。另一方面,如果stdnt被声明为Student,则不会实现私有成员(Name和SayHello),并且会抛出错误。

我猜测接口成员存根(Name& SayHello)默认是Public,以及派生类的访问修饰符定义'实现被忽略。

IMHO。

答案 4 :(得分:1)

C#中的完全等价物如下 - 接口类型的对象可用的方法和其他可用的私有方法:

   void IStudent.SayHello()
   {
       this.SayHello();
   }
   private void SayHello()
   {
       Console.WriteLine("Say Hello!");
   }