T的清单与For Each ...不合作

时间:2018-06-23 20:27:16

标签: vb.net loops for-loop foreach

我无法确切了解为什么会发生这种情况。

(直到获得雇主的SQL权利),我正在开发一个需要身份验证的程序,因此,我正在使用XML文档,并使用XDocument实用程序进行读取。一切都正确地加载到用户集合中。该集合在名为“ UserDatabaseManager”的类中的定义如下:

集合:

Private UserCollection As New List(Of User)

UserCollection的父级定义为:

Public UserDatabaseController As New UserDatabaseManager()

这是User类:

Public Class User
    'CONSTANTS ----------------------------
    Public Enum RoleCode
        BasicQAAgent = 0
        QAAdministrator = 1
        ITadmin = 5
    End Enum

    'VARIABLES ----------------------------
    Dim uname As String = ""
    Dim fname As String = ""
    Dim pass As String = ""
    Dim userrole As RoleCode = 0
    Dim idnumber As Integer = 0
    Dim createDate As String = ""
    Shared Function SerializeUserFromXMLNode(ByVal XMLelement As XElement) As User
        With XMLelement
            Return New User(.@name, .<fullname>.Value, .<creationday>.Value, .<password>.Value, .<role>.Value)
        End With
    End Function

    Public Sub New(ByVal Name As String, ByVal FullName As String, ByVal CreationDay As String, ByVal PassHash As String, ByVal Role As RoleCode)
        fname = FullName : uname = Name : createDate = CreationDay : pass = PassHash : userrole = Role
    End Sub
    Public ReadOnly Property UserName As String
        Get
            Return uname
        End Get
    End Property
    Public ReadOnly Property FullName As String
        Get
            Return fname
        End Get
    End Property
    Public ReadOnly Property UserRoleCode As RoleCode
        Get
            Return userrole
        End Get
    End Property
    Public ReadOnly Property UserIDNumber As Integer
        Get
             Return idnumber
        End Get
    End Property
    Public ReadOnly Property PasswordMD5Hash As String
        Get
            Return pass
        End Get
    End Property
    Public ReadOnly Property CreationDate As Date
        Get
            Return createDate
        End Get
    End Property
End Class

我创建了自己的用户。断点确认我的用户以及所有其他记录均已成功从XDocument加载。我可以的:

UserCollection.Item(0)

和我的用户类将被返回(我知道我在xdocument中的索引为0)。

现在。如果要使用其他字段搜索用户怎么办?

我在用户数据库管理器类(用户集合的父类,用户类和XDocument工具)中有一个函数,该函数会遍历用户,找到与名称匹配的用户,并返回用户的实例调用该函数:

Public Function GetUserByName(ByVal name As String) As User
    For Each usr As User In UserCollection
        If usr.UserName = name Then
            Return usr
        End If
    Next
    Return Nothing
End Function

实际上没有返回总是,实际上,“ If usr.Username ...”上的断点确认ForEach语句甚至没有运行循环!

因此基本上,最终结果是登录屏幕上的 NullObjectReference 。这是在登录屏幕形式中调用GetUserByName的代码:

Private Sub Btn_login_Click(sender As Object, e As EventArgs) Handles btn_login.Click
    DisableLoginElements() 'custom sub
    'try login
    'Try
    Dim inputUsr As String = tbox_Username.Text : Dim inputPass As String = CalculateMD5FromString(tbox_Password.Text)
    tbox_Password.Clear()
    If mainMDI.UserDatabaseController.GetUserByName(inputUsr) IsNot Nothing Then 'HIGHTODO: FIX NULLOBJECTREF FROM USER SEARCH.
        'crosscheck the password provided calculates same MD5 hash as MD5 hash stored in DB. if not, throw MD5calculationVarianceEx Exception
        If mainMDI.UserDatabaseController.GetUserByName(inputUsr).PasswordMD5Hash = inputPass Then
            mainMDI.initializeMainMDIwithUser(mainMDI.UserDatabaseController.GetUserByName(inputUsr)) 'authentication success!
        Else
            Throw MD5calculationVarianceEx 'Password does not match
        End If
    Else
        Throw UserNotFoundEx 'user was not found 
    End If
    'Catch ex As Exception 'an error occured, determine error
    'MsgBox(ex.Message, MsgBoxStyle.Critical, "Login Error: QA Commander")
    'EnableLoginElements()
    'End Try
End Sub

在其中看到HIGHTODO注释的位置将不返回任何内容。我注释掉了Try语句,以进行调试。

请在“ T”代表的对象内按属性帮助我在列表中搜索!

编辑:这是XML和UserDatabaseManager的完整副本:

用户数据库管理器:

Imports System.Collections.ObjectModel
Imports Microsoft

Public Class UserDatabaseManager

Public ReadOnly UserDatabaseManagerVersion As String = "1.0"

Private ReadOnly DBManager As Integer 'User ID Number of the database administrator
Private Company As String
Private Department As String

Private UserCollectionIndex As New Specialized.StringCollection
Public UserCollection As New List(Of User)

Dim xmlMgr As XDocument


Public Sub New(ByVal Optional databaseXMLPath As String = "")
    If Not databaseXMLPath = "" Then
        'Load datasheet from location
        xmlMgr = XDocument.Load(databaseXMLPath)
        If Not xmlMgr.<UserDB>.<version>.@value = UserDatabaseManagerVersion Then 'User Database is outdated.
            Throw UserDBfileVersionMismatchEX
        End If
        DBManager = xmlMgr.<UserDB>.<dbAdministrator>.@value
        Company = xmlMgr.<UserDB>.<company>.@value
        Department = xmlMgr.<UserDB>.<department>.@value
        Dim usersInDB As IEnumerable(Of XElement) = xmlMgr.Descendants("user")
        For Each elm As XElement In usersInDB
            Dim foundName As String = elm.@name
            Dim userEntry As UserDatabaseManager.User = New User(elm.@name, elm.<fullname>.Value, elm.<creationdate>.Value,
                                                                 elm.<password>.Value, elm.<role>.Value)
            UserCollection.Add(User.SerializeUserFromXMLNode(elm))
        Next
    Else
        'create empty instance
    End If
    'get metadeta from XDocument

End Sub

Public Function GetUserByName(ByVal name As String) As User
    For Each usr As User In UserCollection
        If usr.UserName = name Then
            Return usr
        End If
    Next
    Return Nothing
End Function
Private Function GetUserByID(ByVal ID As Integer) As User
    For Each usr As User In UserCollection
        If usr.UserIDNumber = ID Then
            Return usr : Exit Function
        End If
    Next
    Return Nothing
End Function
Public Class User
    'CONSTANTS ----------------------------
    Public Enum RoleCode
        BasicQAAgent = 0
        QAAdministrator = 1
        ITadmin = 5
    End Enum

    'VARIABLES ----------------------------
    Dim uname As String = ""
    Dim fname As String = ""
    Dim pass As String = ""
    Dim userrole As RoleCode = 0
    Dim idnumber As Integer = 0
    Dim createDate As String = ""
    Shared Function SerializeUserFromXMLNode(ByVal XMLelement As XElement) As User
        With XMLelement
            Return New User(.@name, .<fullname>.Value, .<creationday>.Value, .<password>.Value, .<role>.Value)
        End With
    End Function

    Public Sub New(ByVal Name As String, ByVal FullName As String, ByVal CreationDay As String, ByVal PassHash As String, ByVal Role As RoleCode)
        fname = FullName : uname = Name : createDate = CreationDay : pass = PassHash : userrole = Role
    End Sub

    Public ReadOnly Property UserName As String
        Get
            Return uname
        End Get
    End Property
    Public ReadOnly Property FullName As String
        Get
            Return fname
        End Get
    End Property
    Public ReadOnly Property UserRoleCode As RoleCode
        Get
            Return userrole
        End Get
    End Property
    Public ReadOnly Property UserIDNumber As Integer
        Get
            Return idnumber
        End Get
    End Property
    Public ReadOnly Property PasswordMD5Hash As String
        Get
            Return pass
        End Get
    End Property
    Public ReadOnly Property CreationDate As Date
        Get
            Return createDate
        End Get
    End Property
End Class

数据库XML:

<UserDB>
  <version value="1.0" />
  <lastEditedDate value="6/21/2018 3:23PM" />
  <dbAdministrator value="0000001" />
  <company value="Anomaly Squared" />
  <department value ="Quality Assurance" />

  <DBPreferences>
    <DefaultPassword>Password18</DefaultPassword>
    <DefaultPasswordHash>E527FABE14F0F6C0C7AD35886614BEAE</DefaultPasswordHash>
    <ForcePassChangeIfDefault>True</ForcePassChangeIfDefault>
  </DBPreferences>



  <QAAgents>
    <user name="mwendel">
      <userid>0000001</userid>
      <password>8814CD66C7804638B4CCE9233CBF4987</password>
      <fullname>Matthew Wendel</fullname>
      <role>5</role>
      <creationdate>6/23/2018</creationdate>
      <activityHistory>
        <action kind="selfCreatedAccount" date="6/23/2018" result="0x0" />
      </activityHistory>
    </user>

    <user name="jappleseed">
      <userid>0185432</userid>
      <password>E527FABE14F0F6C0C7AD35886614BEAE</password>
      <fullname>Johnny Appleseed</fullname>
      <role>1</role>
      <creationdate>6/23/2018</creationdate>
      <activityHistory>
        <result kind="ITCreatedAccount" date="6/23/2018" result="0x0" />
      </activityHistory>
    </user>
  </QAAgents>


</UserDB>
      User role Definitions
        0 = Basic QA Agent. 
          Ability to:
            • create new evaluations
            • view completed evaluations
            • add employees

        1 = QA Administrator
          Same as basic, but in addition:
            • add/create QA Agent accounts.
            • Can edit previous evaluations.
            • Produce evaluations of Basic QA Agents
            • add/edit/remove campaigns

        5 = IT/Systems Administrator
            Full atonomy to edit and maintain all elements of the system.

1 个答案:

答案 0 :(得分:0)

哇。我实际上可以回答我自己的问题!!!!

因此,调用GetUserByName函数时,它引用的是UserDatabaseManager的默认实例(我声明为UserDatabaseController的实例)中的List(Of User)!

使用关键字 Me 非常重要,因为它可以确保函数指向您声明的对象的实例,而不是默认的空集合。这是更新的功能,一切照常进行:

Public Function GetUserByName(ByVal u_name As String) As User
    For Each usr As User In Me.UserCollection
        If usr.UserName = u_name Then
            Return usr
        End If
    Next
    Return Nothing
End Function

“ .... Me.UserCollection ..中的用户”中的Me标识符基本上解决了此问题。感谢大家的帮助!