ParametrInfo.ParameterType.IsByRef zwraca wartość true, jeśli deklaracja parametru jest ze słowem kluczowym ByRef i zwraca wartość false, jeśli deklaracja jest ze słowem kluczowym ByVal (niezależnie od tego, czy typ parametru jest wartością dodatkową (np. struktura) lub przez odniesienie (np. klasa)).
Aby zilustrować, rozważmy następującą strukturę i klasę (używam kodu VB):
' Empty structure and class, just for illustration.
Public Structure MyStruct
End Structure
Public Class MyClass1
End Class
I załóżmy, że masz następującą metodę, która pobiera ByVal i ByRef argumenty dotyczące struktury i klasy zdefiniowanej powyżej (pamiętać, że wychodząc z VB 2012, można pominąć słowa kluczowego ByVal gdyż jest to ustawienie domyślne):
Public Sub P(s1 As MyStruct, ByRef s2 As MyStruct, c1 As MyClass1, ByRef c2 As MyClass1)
End Sub
teraz następujący kod testuje metodę ParameterInfo.ParameterType.IsByRef:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
' Reflect on method P:
Dim mi As MethodInfo = Me.GetType.GetMethod("P")
' Iterate all parameters, and call its ParameterType.IsByRef method:
For Each pi As ParameterInfo In mi.GetParameters
If **pi.ParameterType.IsByRef** _
Then Console.WriteLine(pi.Name & " is ByRef") _
Else Console.WriteLine(pi.Name & " is ByVal")
Next
End Sub
otrzymasz następujący komunikat:
s1 is ByVal
s2 is ByRef
c1 is ByVal
c2 is ByRef
Jak widać, ParameterInfo.ParameterType.IsByRef zwraca true argumentów s2 i C2, ponieważ są one określone za pomocą słowa kluczowego ByRef, choć jeden z jest to struktura (typ wartości), a druga to klasa (typ odniesienia); i zwraca wartość false dla argumentów zdefiniowanych za pomocą słowa kluczowego ByVal.
Należy jednak zauważyć, że słowo kluczowe ByVal nie oznacza, że wszystkie argumenty zostaną przekazane jako kopia. Nawet jeśli używane jest to słowo kluczowe (ByVal), jeśli typ jest odsyłaczem (np. Klasa), argument zostanie przekazany jako odniesienie, tak jakby użyto słowa kluczowego ByRef. Oznacza to, że c1 i c2 powyższej metody P OBIEĆ będą przekazywane przez odniesienie, co oznacza, że jeśli P zmieni pole lub właściwość na c1 lub c2, zmiany zostaną odzwierciedlone dla osoby wywołującej. (ByVal i ByRef aby różnica głównie gdy typ to wartość, na przykład w postaci struktury).
Uważaj, @Patrik Hägne. IsOut nie oznacza nawet, że parametr jest przekazywany przez odniesienie. Oznacza to, że nie oznacza to, że parametr jest parametrem "out". Jak niedawno odkryłem, ku mojemu rozczarowaniu. –
@BlairConrad: czy możesz rozwinąć powyższy komentarz? W jakich sytuacjach IsOut nie oznacza, że parametr jest parametrem "out"? – RobSiklos
@RobSiklos, jasne. Obrzydliwa historia jest opowiedziana w [komentarz w FakeItEasy numer 508] (https://github.com/FakeItEasy/FakeItEasy/issues/508#issuecomment-122147155). Niektóre parametry są ozdobione '[Out]'. Na przykład, bufor w 'Stream.Read (byte [], int, int)'. –