VB:对象“由于其保护级别而无法访问"(Visual Studio 2012) [英] VB: Object "inaccessible due to its protection level" (Visual Studio 2012)

查看:403
本文介绍了VB:对象“由于其保护级别而无法访问"(Visual Studio 2012)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

Form1.VB 中的这段代码:

This code in 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 由于其保护级别而无法访问.

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

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

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

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

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

此时的array.vb:

array.vb at the moment:

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

推荐答案

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

Public is not the same as global. In fact, VB.NET doesn't even support Global variables, in the strict old VB6 sense. Even though it's Public, it's still scoped to the Array class, 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 Array object (i.e. instance), not of the class, itself, for instance:

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

但是:

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

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

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 Shared keyword, like this:

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.

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

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 Array which is pretty fundamental.

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

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 Each loop and a List, like this:

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

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

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

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

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

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.

这篇关于VB:对象“由于其保护级别而无法访问"(Visual Studio 2012)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆