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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20426671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 16:02:55  来源:igfitidea点击:

VB: Object "inaccessible due to its protection level" (Visual Studio 2012)

vb.netobjectpublic

提问by TechnoBabblefish

I'm having problems with this SearchButtoncode in VB (Visual Studio 2012):

SearchButton在 VB (Visual Studio 2012)中遇到此代码的问题:

This code in Form1.VB:

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 

and I'm getting an error that artistArrayis inaccessible due to its protection level.

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

I'm new to VB, so I'm sure it's something I'm doing wrong, but I can't find it.

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

I have checked spelling, visibility (Public), and so on.

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

array.vb at the moment:

此刻的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

回答by Steven Doggart

Publicis not the same as global. In fact, VB.NET doesn't even support Globalvariables, in the strict old VB6 sense. Even though it's Public, it's still scoped to the Arrayclass, so you have to access if as a property of that class. However, it's also an instance property, which means it's a member of each Arrayobject (i.e. instance), not of the class, itself, for instance:

Public和全局不一样。事实上,VB.NET 甚至不支持Global严格的旧 VB6 意义上的变量。即使它是Public,它的范围仍然是Array类,因此您必须访问 if 作为该类的属性。然而,它也是一个实例属性,这意味着它是每个Array对象(即实例)的成员,而不是类本身的成员,例如:

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

But:

但:

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

If you want to make it a shared property, meaning it will be a member of the class, itself, rather than each instance of that class, and therefore, effectively global, you need to add the Sharedkeyword, like this:

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

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

Then, you will be able to access it from anywhere in your project, like this:

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

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

Of course, having global variables is almost always a bad design decision, but that's another topic.

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

All of this is a bit confusing too, because you are calling your class Array. Technically, you can do that if you really want to, but I wouldn't advise it since the .NET Framework already includes a class called Arraywhich is pretty fundamental.

所有这些也有点令人困惑,因为您正在调用您的 class Array。从技术上讲,如果您真的想这样做,您可以这样做,但我不建议这样做,因为 .NET Framework 已经包含一个称为Array非常基础的类。

Also, there's no reason to store the search results in a field of the class. It would be far better if that was scoped to be local to the search method. And it would be simpler if you used a For Eachloop and a List, like this:

此外,没有理由将搜索结果存储在类的字段中。如果将其范围限定为搜索方法的本地范围会好得多。如果您使用For Each循环和 a会更简单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

Then, you could call it like this:

然后,你可以这样称呼它:

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

It pains me to even put globals in my example, but there it is. Notice I changed the ToLower.Containsto IndexOf, since that is safer, given certain culture issues. I also changed the resultsvariable in the click event handler to an array, since that is what the method is returning.

把全局变量放在我的例子中让我很痛苦,但它就是这样。请注意,我将 更改ToLower.ContainsIndexOf,因为考虑到某些文化问题,这样更安全。我还将results单击事件处理程序中的变量更改为数组,因为这是该方法返回的内容。

You can also simplify the code even more by using LINQ, like this:

您还可以使用 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

But I would advise you to spend more time learning the fundamentals before you start trying to do anything fancy, like that.

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

回答by ja72

Your whole code can be replaced by a single LINQline

您的整个代码可以用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