代码之家  ›  专栏  ›  技术社区  ›  Patrik Hägne

参考参数和反射

  •  31
  • Patrik Hägne  · 技术社区  · 16 年前

    我不确定这里是否完全缺少了一些东西,但是我找不到任何方法来确定参数是否是通过引用传递的,或者不是通过使用反射传递的。

    ArgumentInfo有一个属性“isout”,但没有“isref”。我将如何获取给定MethodInfo中的所有引用参数?

    5 回复  |  直到 8 年前
        1
  •  38
  •   Rex M    16 年前
    ParameterInfo[] parameters = myMethodInfo.GetParameters();
    foreach(ParameterInfo parameter in parameters)
    {
        bool isRef = parameterInfo.ParameterType.IsByRef;
    }
    
        2
  •  9
  •   RobSiklos    9 年前

    ParameterType.IsByRef 将返回 true 对于两者 ref out 参数。

    如果你有 ParameterInfo 对象(例如来自 MethodInfo.GetParameters() 然后:

    • 帕拉姆群岛 外面的 如果 parameterInfo.ParameterType.IsByRef && parameterInfo.IsOut
    • 帕拉姆群岛 裁判 如果 parameterInfo.ParameterType.IsByRef && parameterInfo.IsOut == false

    如果你不这样做 IsByRef 检查 外面的 参数,则会错误地让成员用 [Out] 属性来自 System.Runtime.InteropServices 但实际上不是C# 外面的 参数。

        3
  •  7
  •   Christian Rodemeyer    16 年前

    您需要进一步检查参数的类型。例如,如果你有

    void Foo(ref int bar)
    

    那么参数的名称就不会是 int Int32 (如你所料)但是 Int32& . 对于每种类型,都有一个对应的“按引用”类型,其中原始类型的后缀是“&”。 您可以通过 IsByRef 性质 Type 班级。

        4
  •  1
  •   Michel Abi Raad    12 年前

    如果参数的声明带有byref关键字,则parameterInfo.parameterType.isByRef返回true;如果声明带有byval关键字,则返回false(无论参数的类型是按值(如结构)还是按引用(如类))。

    为了举例说明,请考虑以下结构和类(我使用的是VB代码):

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

    并且假设您有以下方法,为上面定义的结构和类接受byval和byref参数(注意,从vb 2012开始,您可以省略byval关键字,因为它是默认的):

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

    下面的代码测试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
    

    您将得到以下输出:

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

    如您所见,参数info.parameterType.isByRef对于参数s2和c2返回true,因为它们是用byRef关键字定义的,即使其中一个是结构(值类型),另一个是类(引用类型);对于用byVal关键字定义的参数返回false。

    但是请注意,byval关键字并不意味着所有参数都将作为副本传递。即使使用了这个关键字(byval),如果类型是按引用传递的(例如,类),参数也将按引用传递,就像使用了byref关键字一样。也就是说,上面方法p的c1和c2都将通过引用传递,这意味着如果p将字段或属性更改为c1或c2,则更改将反映到调用方。(当类型是一个值(如结构)时,ByVal和ByRef通常会有所不同。)

        5
  •  0
  •   Turbofish    8 年前

    如果引用是 parameterInfo.IsIn == true && parameterInfo.IsOut == true 那么如果 parameterInfo.ParameterType.IsByRef 完全