Реф параметры и отражение - PullRequest
31 голосов
/ 12 октября 2009

Я не уверен, что я что-то здесь упустил, но я не могу найти способ определить, передан ли параметр по ссылке или нет с помощью отражения.

ArgumentInfo имеет свойство "IsOut", но не имеет "IsRef". Как мне получить все ссылочные параметры в данном MethodInfo?

Ответы [ 5 ]

38 голосов
/ 12 октября 2009
ParameterInfo[] parameters = myMethodInfo.GetParameters();
foreach(ParameterInfo parameter in parameters)
{
    bool isRef = parameterInfo.ParameterType.IsByRef;
}
10 голосов
/ 30 июня 2016

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.

7 голосов
/ 12 октября 2009

Вам необходимо дополнительно изучить тип вашего параметра. Например, если у вас есть

void Foo(ref int bar)

тогда имя параметра будет не int или Int32 (как вы могли бы ожидать), а вместо Int32&. Для каждого типа есть соответствующий by-ref-type, в котором исходный тип имеет суффикс «&». Вы можете проверить это через свойство IsByRef класса Type.

1 голос
/ 24 апреля 2012

ParameterInfo.ParameterType.IsByRef возвращает true, если объявление параметра выполняется с ключевым словом ByRef, и возвращает false, если объявление с ключевым словом ByVal (независимо от того, является ли тип параметра побочным (например, структура) ) или по ссылке (например, класс)).

Для иллюстрации рассмотрим следующую структуру и класс (я использую код 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 возвращает true для аргументов s2 и c2, поскольку они определены с помощью ключевого слова ByRef, даже если один из них является структурой (тип-значения), а другой - классом (ссылка -тип); и возвращает false для аргументов, определенных с помощью ключевого слова ByVal.

Обратите внимание, однако, что ключевое слово ByVal не означает, что все аргументы будут переданы как копия. Даже если используется это ключевое слово (ByVal), если тип является побочной ссылкой (например, класс), аргумент будет передан по ссылке, как если бы использовалось ключевое слово ByRef. Таким образом, c1 и c2 описанного выше метода P будут оба передаваться по ссылке, что означает, что если P изменяет поле или свойство на c1 или c2, изменения будут отражены вызывающей стороне. (ByVal и ByRef имеют значение, главным образом, когда тип является значением, например структурой.)

0 голосов
/ 04 ноября 2016

если ref parameterInfo.IsIn == true && parameterInfo.IsOut == true тогда может не понадобиться, если parameterInfo.ParameterType.IsByRef вообще

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...