您好我只是想在vb中使用Byref和ByVal做一些事情我正在通过一个方法传递我的对象并尝试设置对象的值但是我不清楚它是否有人可以帮助我理解这两个概念clear.Below是我试图改变arr List的值的方法,但是它给出了修改Collection的异常;枚举操作可能无法执行。请帮助理解Byval和Byref的逻辑。
Public Function arrayReturn() As List(Of Object)
Dim arr As List(Of Object)
arr = New List(Of Object)
For index As Integer = 1 To 5
arr.Add(index)
Debug.Write(index.ToString & " ")
Next
For Each i As Object In arr
arr.Add(intReturn(i))
Next
Return arr
End Function
Public Function intReturn(ByRef i As Object) As Integer
i += i
Return i
End Function
Sub Main()
Dim obj As List(Of Object)
obj = New List(Of Object)
obj = arrayReturn()
For Each obj2 As Object In obj
Console.WriteLine(obj2)
Next
End Sub
我的问题在于这个方法在这里我试图检索一个事件对象并把它放在一个事件列表中但是我没有得到我的正确与否
Public Function GetIcalForAppointments(nxtMonth As Integer, prevMonth As Integer, strStaffAPIKey As String) As Ical.NET.Calendar
Dim objDTOIcallApt As DTOICallAppt
objDTOIcallApt = New DTOICallAppt
Dim lst As List(Of DOAppointment)
objDTOIcallApt = GetAllAppointmentsForIcal(nxtMonth, prevMonth, strStaffAPIKey)
lst = objDTOIcallApt.Appointments
Dim timeZoneName As String = objDTOIcallApt.UserTimezone
Dim calendar As Ical.NET.Calendar
calendar = New Ical.NET.Calendar()
Dim timeZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName)
calendar.AddTimeZone(New Ical.NET.VTimeZone(timeZoneName))
Dim evt As Ical.NET.Event
For Each appt As DOAppointment In lst
GetIcalForAppointment(appt, objDTOIcallApt, calendar, evt)
Next
Return calendar
End Function
Public Function GetIcalForAppointment(app As DOAppointment, objResponse As DTOICallAppt, calendar As Ical.NET.Calendar, ByRef evt As Ical.NET.Event) As Ical.NET.Event
evt = calendar.Create(Of Ical.NET.Event)()
evt.Start = getCalDateTime(app.StartDate, calendar)
evt.End = getCalDateTime(app.EndDate, calendar)
evt.Description = app.FullSubject
evt.Location = app.AppointmentInOrgName
evt.IsAllDay = False
evt.Created = getCalDateTime(app.CreatedDatetime, calendar)
If objResponse.UserEmail <> "" AndAlso objResponse.UserEmail.Contains("@") = True Then
evt.Organizer = New Organizer("MAILTO:" + objResponse.UserEmail)
End If
Select Case app.AppointmentStatus
Case "Cancelled"
evt.Status = Ical.NET.EventStatus.Cancelled
Exit Select
Case "NoShow"
evt.Status = Ical.NET.EventStatus.Cancelled
Exit Select
Case "Scheduled"
evt.Status = Ical.NET.EventStatus.Tentative
Exit Select
Case Else
evt.Status = Ical.NET.EventStatus.Confirmed
Exit Select
End Select
evt.Categories.Add("Work")
evt.Comments.Add(app.CreatedDetails)
evt.Resources.Add(app.Resource1Name)
evt.Resources.Add(app.Resource2Name)
Dim strSummary As String = app.FullSubject
If app.IsPatConsentRequired = True Then
If app.IsPatConsentGiven = True Then
strSummary = strSummary & Convert.ToString(" | Consent given")
Else
strSummary = strSummary & Convert.ToString(" | Consent Pending")
End If
End If
If app.PatMedicalHistoryCasesheetID <> "" Then
If app.IsMedicalHistoryFilled = True Then
strSummary = strSummary & Convert.ToString(" | Medical History filled")
Else
strSummary = strSummary & Convert.ToString(" | Medical History pending")
End If
End If
evt.Summary = strSummary
evt.Uid = app.ID
Dim alarm As New Ical.NET.Alarm
alarm.Action = Ical.NET.AlarmAction.Display
alarm.Summary = "Appointment with " + app.AppointmentWithFullName + " at " + app.AppointmentInOrgName
alarm.Trigger = New Trigger(TimeSpan.FromMinutes(-30))
evt.Alarms.Add(alarm)
Return evt
End Function
所以在这里你可以看到我正在检索单个事件对象并尝试每次都在事件列表中将其推送
答案 0 :(得分:1)
首先,我不认为ByVal和ByRef与您的问题有关。详细了解他们here 我相信您的问题与您使用的逻辑有关。 让我们分解你的arrayReturn函数,看看发生了什么:
Public Function arrayReturn() As List(Of Object)
Dim arr As List(Of Object)
arr = New List(Of Object)
您正在声明并实例化一个通用的对象列表,这很好。顺便说一句,你可以在一行Dim arr中将这段代码缩短为新的List(Of Object)。
For index As Integer = 1 To 5
arr.Add(index)
Debug.Write(index.ToString & " ")
Next
你在列表中添加了5个对象,这里没有错。
For Each i As Object In arr
这是重点。这个陈述实际上是你和VB之间的契约,你在这里说的是&#34;对于列表中的5个对象中的每一个做了什么&#34;。也就是说,您指示VB为列表中的5个对象中的每个对象执行某些操作,或者更具体,对于此特定时间点列表中当前总对象的每个对象。
VB内部的工作是准备环境来迭代列表中的所有对象,在本例中为5。
arr.Add(intReturn(i))
这是您违约的地方。您正在列表中添加另一个对象,因此不再有5个对象,并且迭代无法继续,因为VB为5个对象准备了所有对象,而不是6个。
这是正确的行为,您在迭代列表期间时无法更改对象的数量。但是,让我们说,为了摆弄这个例子,你能够做到这一点。在这种情况下,你的循环永远不会完成,因为你要告诉VB为列表中的每个对象执行一个动作,并且每次添加一个项目时。如果要考虑该项目,那么每个&#34;每个&#34;会变得无限,因此循环将是无止境的。我希望你明白这一点
Next
Return arr
End Function
我从您的代码中理解的是,您希望在列表中添加相同数量的对象与当前存在的对象,在这种情况下为5.如果这是真的那么您必须修改您的函数,如下所示:
Public Function arrayReturn() As List(Of Object)
Dim arr As New List(Of Object)
For index As Integer = 1 To 5
arr.Add(index)
Debug.Write(index.ToString & " ")
Next
Dim c as Integer = arr.Count
For i As Integer = 0 to c - 1
arr.Add(intReturn(arr(i)))
Next
Return arr
End Function
然而,对于约会应用范围而言,这并不正确。例如,如果在其他约会中有子约会,那么您需要一个不同的存储结构,如树,并以递归方式访问/操作它。
希望这会有所帮助。