我遇到了一个问题,它挑战了我对VB.Net中访问修饰符的理解。我有一个class declare Friend。如果我将其属性声明为Public,应用程序就可以工作。如果我将它们声明为Friend,应用程序就会失败。
在此之前,我认为,在声明为Friend的类中,声明成员Public或Friend在功能上没有区别。我认为类访问声明将它们的限制应用于所有嵌套实体,因此声明为Public的嵌套属性就像声明为Friend一样有效地受到限制。显然,我错了。谁能解释一下访问修饰符是如何工作的,或者告诉我相关的文档?这里是一个更详细的情况描述:我有一个名为StripTask的Friend类,其属性名为StripDate, HistorianDate和TaskText。我有一个StripTasks(称为_StripTasks)的集合,它被用作Syncfusion GridDataBoundGrid的数据源。绑定的工作方式是,我需要将StripTask属性的名称传递给每个网格列,以便每个列知道要显示什么数据。它最终看起来像这样:_DataBoundGrid.GridBoundColumns(1)。MappingName = "StripDate"。当将映射属性声明为Public时,它就可以工作了。当将映射的属性声明为Friend时,将用正确数量的行填充网格,但是每个单元格都是空的。
作为一个后续问题,这是一个好主意,以避免事情,如这个Syncfusion绑定方法,这需要我传递属性名称作为字符串?感觉我好像在自找麻烦。
不,类的访问级别不会渗透到成员和方法。在VB中,如果你不指定任何东西,所有的方法都是Public
。如果你把一些东西标记为Friend
,你是在说你不希望你的程序集之外的代码能够访问它,这听起来就像你所看到的。
编辑
重要的是要理解类级别的访问规则主要处理实例化和类型化。想象一下下面的DLL,它使用反射来查看给定对象的属性(这几乎肯定是Syncfusion所做的):Option Explicit On
Option Strict On
Public Class Class1
Public Sub Process(ByVal obj As Object)
Dim T = obj.GetType()
Dim Props = T.GetProperties()
For Each P In Props
Trace.WriteLine(P.Name)
Next
End Sub
End Class
然后想象下面的WinForms应用程序在一个单独的程序集中,并引用上面的DLL:
Option Explicit On
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim X As New ClassLibrary1.Class1()
Dim FC As New FriendClass()
Dim PC As New PrivateClass()
X.Process(FC)
X.Process(PC)
End Sub
Private Class PrivateClass
Public Property PublicProp As String
Friend Property FriendProp As String
Private Property PrivateProp As String
End Class
End Class
Friend Class FriendClass
Public Property PublicProp As String
Friend Property FriendProp As String
Private Property PrivateProp As String
End Class
你可以传递一个Friend
类和一个Private
类到另一个程序集,这是完全有效的。然而,另一方面,DLL将无法访问Friend
或Private
属性,只能访问Public
属性。当它运行时,你会在Immediate窗口中看到两行PublicProp
,这是它唯一可以看到的属性。