属性。有什么有用的目的?

发布于 2024-10-13 12:28:17 字数 271 浏览 8 评论 0原文

System.Runtime.InteropServices 下,存在 属性。 但它有什么用呢?如果您可以使用以下示例作为答案的基础,我将很高兴。

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

Under System.Runtime.InteropServices the <Out()> Attribute exists.
But what is it for? I would be glad if you could use the following example as base for your answers.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

可爱咩 2024-10-20 12:28:17

该属性的目的有两个:

  • 调用站点处理,是否强制变量初始化
  • 编组

如果要从 C# 或具有类似语义的类似语言调用该方法,编译器将知道此类参数不会存在需要一个初始值。

换句话说,您可以这样做:

int a;
CallSomeMethodWithOutParameter(out a);

并且编译器知道在进行调用之前无需确保 a 已经具有值。

另一方面,如果没有该属性,则需要以下内容(同样在 C# 中):

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

另一个目的是将方法调用编组到不同的调用上下文中,例如通过 P/Invoke 编组到不同的应用程序域,或者发送至 Web 服务,通知编组例程该方法返回时相关参数将包含一个值,但在调用该方法时无需将任何值传递到该方法中。

当需要打包参数和返回值并将其传输到实际调用所经过的远程位置时,这可能会产生影响。

换句话说,如果您要指定在通过 P/Invoke 使用的方法调用上,则当该方法调用时,不会对现有参数值进行编组,但当该方法返回它的值被提升回您的调用代码。

请注意,此优化取决于要使用或不使用的编组例程,这些是实现细节。该属性只是告诉例程它可以使用哪些参数来执行此操作,而不是始终遵循的指令。

The purpose of that attribute is twofold:

  • Call-site handling, whether to enforce variable initialization or not
  • Marshalling

If you were to call that method from C#, or a similar language with similar semantics, such a parameter would be known to the compiler to not need an initial value.

In other words, you can do this:

int a;
CallSomeMethodWithOutParameter(out a);

and the compiler knows that there is no need to ensure that a already has a value before making the call.

On the other hand, without the attribute, the following would be needed, again in C#:

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

The other purpose is for method calls that will be marshalled into a different calling context, for instance through P/Invoke, to a different app-domain, or to a web service, to notify marshalling routines that the parameter in question will contain a value when the method returns, but there is no need to pass any value into the method when calling it.

This might make a difference when parameters and return values needs to be packaged up and transported to the remote location where the actual call goes through.

In other words, if you were to specify that on a method call used through P/Invoke, no marshalling will be done of the existing parameter value when the method is called, but when the method returns its value is lifted back into your calling code.

Note that this optimization is up to the marshalling routine to use, or not, these are implementation details. The attribute just tells the routine which parameters it can do that with, it is not an instruction that will always be followed.

痴情 2024-10-20 12:28:17

一方面,这意味着该参数被 C# 视为“输出”参数。在这种情况下,C# 编译器将假定:

  • 通过引用传递的变量的任何现有值都是无关紧要的,因此明确的赋值并不重要
  • 在变量被分配一个适当的值时方法返回,除非有异常 - 所以它肯定是在语句末尾分配的。

当然,其他语言可能会选择以不同的方式使用 [Out] 属性,但这种解释是最自然的。基本上它说参数几乎就像一个额外的返回值。 (当然,存在很多不同程度的细微差别,但这是输出参数的一般感觉。)

It means the parameter is seen as an "out" parameter by C#, for one thing. In that case, the C# compiler will assume that:

  • Any existing value of the variable passed by reference is irrelevant, so definite assignment doesn't matter
  • The variable will have been assigned an appropriate value by the time the method returns, unless there's an exception - so it's definitely assigned at the end of the statement.

Other languages may choose to use the [Out] attribute in different ways, of course, but that sort of interpretation is the most natural one. Basically it says that the parameter is almost like an extra return value. (There are plenty of differences of course, of varying degrees of subtlety, but that's the general feeling of an out parameter.)

巷子口的你 2024-10-20 12:28:17

它在 ComVisible 类型中使用,指示生成的 COM 类型库应使用 [out] 属性来修饰参数。

It is used in ComVisible types to indicate that the generated COM type library should decorate the parameter with the [out] attribute.

影子的影子 2024-10-20 12:28:17

我不了解 VB,但假设它相当于 C# 的 out 关键字:

它的行为就像 ref 但不需要调用者初始化传递给的变量out 参数,因为该函数不会读取它。

如果您使用 COM 或 p-invoke,它可能会对封送处理产生影响。

I don't know about VB, but assuming it's equivalent to C#'s out keyword:

It behaves just like ref but doesn't require the caller to initialize the variable passed to the out parameter because the function won't read it.

And it probably has an effect on marshaling if you use COM oder p-invoke.

爱她像谁 2024-10-20 12:28:17

当应用于方法参数和返回值时,此属性控制编组方向,因此称为方向属性。 [OutAttribute] 告诉 CLR 在返回时从被调用者封送回调用者。调用者和被调用者都可以是非托管或托管代码。例如,在 P/Invoke 调用中,托管代码正在调用非托管代码。然而,在反向 P/Invoke 中,非托管代码可以通过函数指针调用托管代码。

在某些情况下,[OutAttribute] 将被忽略。例如,[OutAttribute]int 没有任何意义,因此 CLR 会忽略 [OutAttribute][OutAttribute] 字符串也是如此,因为字符串是不可变的。

因此,对于您的示例,此属性没有意义。有关此属性和相关 属性的更多信息,您可以找到 这里

When applying to method parameters and return values, this attributes control marshaling direction, so it's known as directional attributes. [OutAttribute] tells the CLR to marshal back from the callee to the caller upon return. Both the caller and the callee can be either unmanaged or managed code. For example, in a P/Invoke call, managed code is calling unmanaged code. However, in a reverse P/Invoke, unmanaged code could call managed code through a function pointer.

There are cases when [OutAttribute] will be ignored. For example, [OutAttribute]int doesn't make any sense, so the [OutAttribute] is simply ignored by the CLR. The same is true of [OutAttribute] string because string is immutable.

So, for your example this attribute doesn't have a sense. More about this attribute and correlated <In()> attribute your can find here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文