The Attribute. What useful purpose does is s

2020-07-08 08:54发布

问题:

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

回答1:

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.



回答2:

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.)



回答3:

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



回答4:

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.



回答5:

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.