VB:对象“由于其保护级别而无法访问”(Visual Studio 2012)

问题描述 投票:0回答:2

我在VB中使用这个SearchButton代码有问题(Visual Studio 2012):

Form1.VB中的此代码:

Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click 
    Dim results As Artist 
    results = Array.SearchArray(artistArray(), SearchTextBox.Text) 
End Sub 

而且由于其保护级别,我收到artistArray无法访问的错误。

我是VB的新手,所以我确定这是我做错了,但我找不到它。

我检查了拼写,可见性(Public),等等。

array.vb此刻:

Public Class Array 
    Public artistArray() As Artist 
    Public searchResults(artistArray.Length) As Artist 
    Dim searchString As String 

    Public Function SearchArray(ByVal artistArray(), searchString) As Artist() 
        Dim x As Integer ' artist index variable for loop 
        Dim index As Integer = 0 ' index for results 
        For x = 0 To artistArray.GetUpperBound(0) 
            Dim temp As Artist = artistArray(x) 
            If temp.Name.ToLower().Contains(searchString.ToLower()) Then 
                searchResults(index) = artistArray(x) ' if search hit then add current item to result array 
                index += 1 ' and incr. result index 
            End If 
         Next 
         ReDim Preserve searchResults(index) 
         Return searchResults 
    End Function 

    ' ...
End Class
vb.net object public
2个回答
1
投票

Public与全球不同。事实上,VB.NET甚至不支持Global变量,在严格的旧VB6意义上。即使它是Public,它仍然是Array类的范围,所以如果作为该类的属性你必须访问。但是,它也是一个实例属性,这意味着它是每个Array对象(即实例)的成员,而不是类本身的成员,例如:

Dim first As Artist = Array.artistArray(0)  ' Does not work

但:

Dim a As New Array()
Dim first As Artist = a.artistArray(0)  ' Works

如果你想让它成为一个共享属性,意味着它将成为类的成员本身,而不是该类的每个实例,因此,有效的全局,你需要添加Shared关键字,如下所示:

Public Class Array
    Public Shared arrayArtist() As Artist
    ' ...
End Class

然后,您将能够从项目的任何位置访问它,如下所示:

Dim first As Artist = Array.artistArray(0)  ' Works now

当然,拥有全局变量几乎总是一个糟糕的设计决策,但这是另一个主题。

所有这一切都有点令人困惑,因为你打电话给你的班级Array。从技术上讲,如果你真的想要,你可以这样做,但我不建议它,因为.NET Framework已经包含一个名为Array的类,这是非常基础的。

此外,没有理由将搜索结果存储在类的字段中。如果将搜索范围放在搜索方法的本地范围内会好得多。如果你使用For Each循环和List会更简单,如下所示:

Public Class ArtistBusiness
    Public Shared Artists() As Artist

    Public Shared Function SearchArtists(artists() As Artist, searchString As String) As Artist()
        Dim results As New List(Of Artist)()
        For Each i As Artist In artists
            If i.Name.IndexOf(searchString, StringComparison.CurrentCultureIgnoreCase) >=0 Then
                results.Add(i)
            End If
        Next
        Return results.ToArray()
    End Function
End Class

然后,你可以像这样调用它:

Private Sub SearchButton_Click(sender As Object, e As EventArgs) Handles SearchButton.Click 
    Dim results() As Artist 
    results = ArtistBusiness.SearchArtists(ArtistBusiness.Artists, SearchTextBox.Text) 
End Sub

甚至把全局变量放在我的例子中也让我感到痛苦,但事实确实如此。请注意,我将ToLower.Contains更改为IndexOf,因为考虑到某些文化问题,这更安全。我还将click事件处理程序中的results变量更改为数组,因为这是该方法返回的内容。

您还可以使用LINQ进一步简化代码,如下所示:

Public Shared Function SearchArtists(artists() As Artist, searchString As String) As Artist()
    artists.Select(Function(x) x.Name.IndexOf(searchString, StringComparison.CurrentCultureIgnoreCase) >= 0).ToArray()
End Function

但是我建议你在开始尝试做任何花哨的事情之前花更多时间学习基础知识。


0
投票

您的整个代码可以替换为单个LINQ

Public artists As Artist()

Public Function FindArtists(searchString As String) As Artist()
    Return artists.Where(Function(a) a.Name.ToLower().Contains(searchString)).ToArray()
End Function
© www.soinside.com 2019 - 2024. All rights reserved.