Атрибут.Какая полезная цель служит? - PullRequest
7 голосов
/ 24 января 2011

Под System.Runtime.InteropServices существует атрибут <Out()>. Но для чего это нужно? Я был бы рад, если бы вы могли использовать следующий пример в качестве основы для ваших ответов.

 Shared Sub Add(ByVal x As Integer, ByVal y As Integer, <Out()> ByRef Result As Integer)
  Result = x + y
 End Sub

Ответы [ 5 ]

7 голосов
/ 24 января 2011

Назначение этого атрибута двоякое:

  • Обработка вызова сайта, для принудительной инициализации переменной или нет
  • Ранжирование

Если бы вы вызывали этот метод из C # или подобного языка с похожей семантикой, такой параметр был бы известен компилятору, чтобы не нуждаться в начальном значении.

Другими словами, вы можете сделать это:

int a;
CallSomeMethodWithOutParameter(out a);

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

С другой стороны, без атрибута потребуется следующее, опять же в C #:

int a = 0;                               // <-- notice initialization here
CallSomeMethodWithOutParameter(ref a);   // <-- and ref here

Другая цель для вызовов методов, которые будут перенаправляться в другой контекст вызова, например, через P / Invoke, в другой домен приложения или в веб-службу, чтобы уведомить процедуры маршалинга о том, что рассматриваемый параметр содержать значение при возврате метода, но нет необходимости передавать какое-либо значение в метод при его вызове.

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

Другими словами, если указать, что при вызове метода, используемого через P / Invoke, не будет выполнено маршалинг существующего значения параметра, когда метод называется , но когда метод возвращает его значение возвращается в ваш код вызова.

Обратите внимание, что эта оптимизация зависит от используемой процедуры маршалинга, или нет, это детали реализации. Атрибут просто сообщает подпрограмме, с какими параметрами он может сделать это, это не инструкция, которой всегда будут следовать.

3 голосов
/ 24 января 2011

Это означает, что параметр рассматривается как параметр "out" в C #, с одной стороны.В этом случае компилятор C # будет считать, что:

  • Любое существующее значение переменной, переданной по ссылке, не имеет значения, поэтому определенное присваивание не имеет значения
  • Переменная будет ли присвоено соответствующее значение ко времени возврата метода, если только нет исключения - поэтому оно определенно назначается в конце оператора.

Другие языки могут использовать [Out] приписывают, конечно, по-разному, но такое толкование является наиболее естественным.В основном это говорит о том, что параметр почти как дополнительное возвращаемое значение.(Конечно, существует множество различий различной степени тонкости, но это общее ощущение выходного параметра.)

2 голосов
/ 24 января 2011

Используется в типах ComVisible, чтобы указать, что сгенерированная библиотека типов COM должна украшать параметр атрибутом [out].

0 голосов
/ 24 января 2011

При применении к параметрам метода и возвращаемым значениям эти атрибуты управляют направлением маршалинга, поэтому оно называется направленными атрибутами. [OutAttribute] приказывает CLR по возвращении от вызываемого к вызывающему. И вызывающий, и вызываемый могут быть как неуправляемым, так и управляемым кодом. Например, в вызове P / Invoke управляемый код вызывает неуправляемый код. Однако в обратном P / Invoke неуправляемый код может вызывать управляемый код через указатель функции.

Бывают случаи, когда [OutAttribute] будет игнорироваться. Например, [OutAttribute]int не имеет никакого смысла, поэтому [OutAttribute] просто игнорируется CLR. То же самое верно для [OutAttribute] строки, потому что строка неизменна.

Итак, для вашего примера этот атрибут не имеет смысла. Подробнее об этом атрибуте и соответствующем атрибуте <In()> вы можете найти здесь .

0 голосов
/ 24 января 2011

Я не знаю о VB, но предполагая, что оно эквивалентно ключевому слову out в C #:

Оно ведет себя так же, как ref, но не требует, чтобы вызывающая сторона инициализировала переменную, переданную *Параметр 1005 *, потому что функция не будет его читать.

И, вероятно, он повлияет на маршалинг, если вы используете COM-oder p-invoke.

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