我不确定我是否完全错过了这里的内容,但我找不到任何方法来确定参数是否通过引用传递,或者不使用反射。
ArgumentInfo有一个属性“IsOut”,但没有“IsRef”。我如何获得给定MethodInfo中的所有参考参数?
答案 0 :(得分:38)
ParameterInfo[] parameters = myMethodInfo.GetParameters();
foreach(ParameterInfo parameter in parameters)
{
bool isRef = parameterInfo.ParameterType.IsByRef;
}
答案 1 :(得分:9)
ParameterType.IsByRef
和 true
参数, ref
将返回out
。
如果您有ParameterInfo
个对象(例如来自MethodInfo.GetParameters()
),那么:
out
parameterInfo.ParameterType.IsByRef && parameterInfo.IsOut
ref
parameterInfo.ParameterType.IsByRef && parameterInfo.IsOut == false
如果您未IsByRef
检查out
个参数,那么您将错误地从[Out]
获取使用System.Runtime.InteropServices
属性修饰的成员但实际上并不是C#out
参数。
答案 2 :(得分:7)
您需要进一步检查参数的类型。例如,如果你有
void Foo(ref int bar)
然后参数的名称将不是int
或Int32
(正如您可能预期的那样),而是Int32&
。对于每种类型,都有一个对应的by-ref-type,其中原始类型后缀为'&'。
您可以通过IsByRef
类的Type
属性进行检查。
答案 3 :(得分:1)
如果参数的声明带有ByRef关键字,则ParameterInfo.ParameterType.IsByRef返回true;如果声明带有ByVal关键字,则返回false(无论参数的类型是否为by-value(例如,结构) )或通过引用(例如,类))。
为了说明,请考虑以下结构和类(我正在使用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
如您所见,ParameterInfo.ParameterType.IsByRef为参数s2和c2返回true,因为它们是使用ByRef关键字定义的,即使其中一个是结构(值类型)而另一个是类(引用) -类型);并为使用ByVal关键字定义的参数返回false。
但请注意,ByVal关键字并不意味着所有参数都将作为副本传递。即使使用了这个关键字(ByVal),如果类型是引用(例如,类),则参数将通过引用传递,就像使用了ByRef关键字一样。也就是说,上述方法P的c1和c2将通过引用传递,这意味着如果P将字段或属性更改为c1或c2,则更改将反映给调用者。 (ByVal和ByRef主要在类型为值时产生差异,例如结构。)
答案 4 :(得分:0)
如果ref为parameterInfo.IsIn == true && parameterInfo.IsOut == true
然后可能不需要parameterInfo.ParameterType.IsByRef