ランタイム?まったくありません。refまたはoutキーワードのみが異なる同じパラメーターを持つメソッドをオーバーロードすることはできません。
これをコンパイルしようとすると、「同じ署名のメソッドが既に宣言されています」というコンパイルエラーが表示されます。
private class MyClass
{
private void DoSomething(out int param)
{
}
private void DoSomething(ref int param)
{
}
}
この質問に答えるには:
「... C#に非常に類似した2つの非常に狭いユースケースのツールがあるのはなぜですか?」
コードの読みやすさとAPIの観点からは、大きな違いがあります。APIのコンシューマーとして、「out」が使用される場合、APIはoutパラメーターに依存しないことを知っています。API開発者として、「out」を好み、絶対に(まれに!)必要な場合にのみ「ref」を使用します。すばらしい議論については、このリファレンスを参照してください。
/programming/1516876/when-to-use-ref-vs-out
サポート情報:次のメソッドをコンパイルし、分解しました。refキーワードとoutキーワード(この例ではout)を使用しましたが、予想どおりアドレス参照を除いてアセンブリコードは変更されませんでした。
private class MyClass
{
internal void DoSomething(out int param)
{
param = 0;
}
}
00000000 push ebp
00000001 mov ebp、esp
00000003 push edi
00000004 push esi
00000005 push ebx
00000006 sub esp、34h
00000009 xor eax、eax
0000000b mov dword ptr [ebp-10h]、eax
0000000e mov dword ptr [ebp-1Ch]、eax
00000011 mov dword ptr [ebp-3Ch]、ecx
00000014 mov dword ptr [ebp-40h]、edx
00000017 cmp dword ptr ds:[008B1710h]、0
0000001e je 00000025
00000020 call 6E6B601E
00000025 nop
param = 0;
00000026 mov eax、dword ptr [ebp-40h]
00000029 xor edx、edx
0000002b mov dword ptr [eax]、edx
}
0000002d nop
0000002e lea esp、[ebp-0Ch]
00000031 pop
ebx
00000032 pop esi
00000033 pop edi
00000034 pop ebp
00000035 ret
アセンブリを正しく読んでいますか?
ref
C ++ と同じ方法で実装されています。問題のオブジェクトポインター(またはプリミティブ)へのポインター。すなわち、Int32.TryParse(myStr, out myInt)
(C#)はint32_tryParse(myStr, &myInt)
(C)と同じ方法で「実行」されます。唯一の違いは、バグを防ぐためにコンパイラによって強制されるいくつかの制約です。(これが舞台裏でどのように機能するかについて間違っている可能性があるため、これを回答として投稿するつもりはありませんが、これは(理にかなっているので)動作を想像する方法です)