ParameterInfo.ParameterType.IsByRef devuelve verdadero si la declaración del parámetro es con la palabra clave ByRef, y devuelve falso si la declaración es con la palabra clave ByVal (independientemente de si el tipo del parámetro es por valor (por ejemplo, estructura) o referencia (por ejemplo, clase)).
Como ejemplo, consideremos la siguiente estructura y la clase (estoy usando el código VB):
' Empty structure and class, just for illustration.
Public Structure MyStruct
End Structure
Public Class MyClass1
End Class
Y supongamos que tiene el siguiente método que toma ByVal y ByRef argumentos a favor de la estructura y la clase definida anteriormente (tenga en cuenta que a partir de 2012 VB, puede omitir la palabra clave ByVal, ya que es el valor por defecto):
Public Sub P(s1 As MyStruct, ByRef s2 As MyStruct, c1 As MyClass1, ByRef c2 As MyClass1)
End Sub
Ahora el siguiente código prueba el método 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
obtendrá el siguiente resultado:
s1 is ByVal
s2 is ByRef
c1 is ByVal
c2 is ByRef
Como se puede ver, ParameterInfo.ParameterType.IsByRef devuelve verdadero para los argumentos s2 y c2, ya que se definen con la palabra clave ByRef, a pesar de que uno de ellos son una estructura (tipo de valor) y la otra es una clase (tipo de referencia); y devuelve falso para los argumentos definidos con la palabra clave ByVal.
Tenga en cuenta, sin embargo, que la palabra clave ByVal no significa que todos los argumentos se pasarán como una copia. Incluso si se utiliza esta palabra clave (ByVal), si el tipo es por referencia (por ejemplo, clase), el argumento se pasará por referencia, como si se utilizara la palabra clave ByRef. Es decir, c1 y c2 del método P anterior se pasarán ambos por referencia, lo que significa que si P cambia un campo o propiedad a c1 o c2, los cambios se reflejarán en la persona que llama. (ByVal y ByRef hacen diferencia sobre todo cuando el tipo es un valor, tal como una estructura.)
cuidado, @Patrik Hagne. IsOut ni siquiera significa que el parámetro se pasa por referencia. Es decir, no significa que el parámetro sea un parámetro de "salida". Como descubrí recientemente, para mi disgusto. –
@BlairConrad: ¿pueden dar más detalles sobre su comentario anterior? ¿En qué situaciones IsOut no significa que el param es un parámetro de "salida"? – RobSiklos
@RobSiklos, claro. La sórdida historia se cuenta en [un comentario en la edición FakeItEasy 508] (https://github.com/FakeItEasy/FakeItEasy/issues/508#issuecomment-122147155). Algunos parámetros están decorados con '[Out]'. Por ejemplo, el búfer en 'Stream.Read (byte [], int, int)'. –