9

属性下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
4

5 回答 5

8

该属性的目的有两个:

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

如果您要从 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 使用的方法调用上指定,则在调用该方法时不会对现有参数值进行编组但是当方法返回时,它的值会被提升回您的调用代码中.

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

于 2011-01-24T11:38:29.910 回答
3

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

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

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

于 2011-01-24T11:34:28.353 回答
2

它用于 ComVisible 类型中,表示生成的 COM 类型库应该用 [out] 属性装饰参数。

于 2011-01-24T14:29:54.123 回答
0

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

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

如果您使用 COM oder p-invoke,它可能会对编组产生影响。

于 2011-01-24T11:33:48.087 回答
0

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

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

因此,对于您的示例,此属性没有意义。<In()>您可以在此处找到有关此属性和相关属性的更多信息。

于 2011-01-24T15:25:13.247 回答