Пожалуйста, объясните поведение, когда класс и член имеют разный доступ - PullRequest
0 голосов
/ 13 апреля 2011

Я столкнулся с проблемой, которая бросает вызов моему пониманию модификаторов доступа в VB.Net.У меня есть класс, объявленный Другом.Если я объявлю его свойства Public, приложение работает.Если я объявляю их Friend, приложение завершается ошибкой.

До этого я полагал, что в классе, объявленном Friend, не будет иметь никакого функционального значения, объявил ли я членов Public или Friend.Я думал, что объявления доступа к классам применяют свои ограничения ко всем вложенным объектам, поэтому вложенные свойства, объявленные как Public, эффективно ограничиваются, как если бы они были объявлены Friend.Очевидно, я был неправ.Может кто-нибудь объяснить, как на самом деле работают модификаторы доступа, или указать мне соответствующую документацию?

Вот более подробное описание ситуации: у меня есть класс Friend с именем StripTask со свойствами StripDate, HistorianDate и TaskText.У меня есть коллекция StripTasks (называемая _StripTasks), которая используется в качестве источника данных для Syncfusion GridDataBoundGrid.Как работает привязка, мне нужно передать имя свойства StripTask каждому из столбцов сетки, чтобы каждый столбец знал, какие данные отображать.В конечном итоге это выглядит примерно так: _DataBoundGrid.GridBoundColumns (1) .MappingName = "StripDate".Когда сопоставленные свойства объявлены как Public, это работает.Когда сопоставленные свойства объявляются Friend, сетка заполняется правильным количеством строк, но каждая ячейка пуста.

В качестве дополнительного вопроса, стоит ли избегать таких вещей, как этаМетод привязки Syncfusion, который требует, чтобы я передавал имена свойств в виде строк?Такое ощущение, что я приглашаю неприятности.

1 Ответ

2 голосов
/ 14 апреля 2011

Нет, уровень доступа класса не зависит от членов и методов. В VB все методы Public, если вы ничего не указали .Если вы помечаете что-то как Friend, вы говорите, что не хотите, чтобы код вне вашей сборки имел к нему доступ, что звучит точно так же, как вы видите.

EDIT

Что важно понять, так это то, что правила доступа на уровне класса имеют дело главным образом с экземплярами и типизацией.Представьте себе следующую 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, которое является единственным свойством, которое оно может видеть.

...