属性の下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
属性の下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
その属性の目的は 2 つあります。
C#、または同様のセマンティクスを持つ同様の言語からそのメソッドを呼び出す場合、そのようなパラメーターは初期値を必要としないことがコンパイラーに認識されます。
言い換えれば、これを行うことができます:
int a;
CallSomeMethodWithOutParameter(out a);
a
コンパイラは、呼び出しを行う前に が既に値を持っていることを確認する必要がないことを認識しています。
一方、属性がない場合は、C# で次のものが必要になります。
int a = 0; // <-- notice initialization here
CallSomeMethodWithOutParameter(ref a); // <-- and ref here
もう 1 つの目的は、たとえば P/Invoke を介して別の呼び出しコンテキスト、別のアプリ ドメイン、または Web サービスにマーシャリングされるメソッド呼び出しで、問題のパラメーターに値が含まれることをマーシャリング ルーチンに通知することです。ただし、メソッドを呼び出すときにメソッドに値を渡す必要はありません。
これは、パラメーターと戻り値をパッケージ化して、実際の呼び出しが行われるリモートの場所に転送する必要がある場合に違いを生む可能性があります。
つまり、P/Invoke を介して使用されるメソッド呼び出しで指定した場合、メソッドが呼び出されたときに既存のパラメーター値のマーシャリングは行われませんが、メソッドが返されたときにその値が呼び出し元のコードに戻されます。 .
この最適化は、使用するかどうかはマーシャリング ルーチン次第であることに注意してください。これらは実装の詳細です。属性は、それを行うことができるパラメーターをルーチンに伝えるだけであり、常に従う命令ではありません。
これは、パラメーターが C# によって "out" パラメーターとして認識されることを意味します。その場合、C# コンパイラは次のことを想定します。
もちろん、他の言語では[Out]
属性をさまざまな方法で使用することを選択できますが、そのような解釈が最も自然な解釈です。基本的には、パラメーターは追加の戻り値のようなものです。(もちろん、さまざまな程度の微妙な違いがたくさんありますが、それが出力パラメーターの一般的な感覚です。)
ComVisibleタイプで使用され、生成されたCOMタイプライブラリが[out]属性でパラメータを装飾する必要があることを示します。
メソッドパラメータと戻り値に適用する場合、この属性はマーシャリングの方向を制御するため、方向属性と呼ばれます。[OutAttribute]
復帰時に呼び出し先から呼び出し元にマーシャリングするようにCLRに指示します。呼び出し元と呼び出し先の両方が、アンマネージコードまたはマネージコードのいずれかになります。たとえば、P / Invoke呼び出しでは、マネージコードはアンマネージコードを呼び出しています。ただし、逆P / Invokeでは、アンマネージコードが関数ポインターを介してマネージコードを呼び出す可能性があります。
[OutAttribute]
無視される場合があります。たとえば、[OutAttribute]int
意味がないため[OutAttribute]
、CLRでは単に無視されます。[OutAttribute]
文字列は不変であるため、同じことが文字列にも当てはまります。
したがって、あなたの例では、この属性には意味がありません。この属性と相関<In()>
属性の詳細については、こちらをご覧ください。
VBについてはわかりませんが、C#のout
キーワードと同等であると仮定します。
これは同じように動作しますが、関数が変数を読み取らないため、呼び出し元がパラメーターref
に渡された変数を初期化する必要はありません。out
また、COMまたはp-invokeを使用すると、マーシャリングに影響を与える可能性があります。