Ref parameters and reflection

前端 未结 5 1927
北恋
北恋 2020-12-29 02:51

I\'m not sure if I\'m totally missing something here but I can\'t find any way to determine if a parameter is passed by reference or not by using reflection.

Argumen

5条回答
  •  时光说笑
    2020-12-29 03:13

    ParameterInfo.ParameterType.IsByRef returns true if the declaration of the parameter is with the ByRef keyword, and returns false if the declaration is with the ByVal keyword (regardless of whether the type of the parameter is by-value (e.g., structure) or by-reference (e.g., class)).

    To illustrate, consider the following structure and class (I'm using VB code):

    ' Empty structure and class, just for illustration.
    Public Structure MyStruct
    End Structure
    
    Public Class MyClass1
    End Class
    

    And suppose you have the following method that takes ByVal and ByRef arguments for the structure and class defined above (note that starting with VB 2012, you can omit the ByVal keyword as it is the default):

    Public Sub P(s1 As MyStruct, ByRef s2 As MyStruct, c1 As MyClass1, ByRef c2 As MyClass1)
    End Sub
    

    Now the following code tests the ParameterInfo.ParameterType.IsByRef method:

    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
    

    You'll get the following output:

    s1 is ByVal
    s2 is ByRef
    c1 is ByVal
    c2 is ByRef
    

    As you can see, ParameterInfo.ParameterType.IsByRef returns true for arguments s2 and c2 because they are defined with the ByRef keyword, even though one of them is a structure (value-type) and the other is a class (reference-type); and returns false for the arguments defined with the ByVal keyword.

    Note, however, that the ByVal keyword does not mean that all arguments would be passed as a copy. Even if this keyword (ByVal) is used, if the type is by-reference (e.g., class), the argument would be passed by reference, as if the ByRef keyword were used. That is, c1 and c2 of method P above will BOTH be passed by reference, which means that if P changes a field or property to c1 or c2, the changes will be reflected to the caller. (ByVal and ByRef make difference mostly when the type is a value, such as a structure.)

提交回复
热议问题