Подтвердить что ты не робот

Параметры и отражение

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

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

4b9b3361

Ответ 1

ParameterInfo[] parameters = myMethodInfo.GetParameters();
foreach(ParameterInfo parameter in parameters)
{
    bool isRef = parameterInfo.ParameterType.IsByRef;
}

Ответ 2

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

void Foo(ref int bar)

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

Ответ 3

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, но не являющиеся фактически параметрами С# out.

Ответ 4

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 делают разницу главным образом, когда тип является значением, таким как структура.)

Ответ 5

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