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
VB: Object "inaccessible due to its protection level" (Visual Studio 2012)
提问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.Contains为IndexOf,因为考虑到某些文化问题,这样更安全。我还将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

