ここで使用する必要がない理由について、より直接的に回答を書き直すことにしout
ました。あなたの質問の根本は、値渡し、参照渡し、および参照渡しされる参照型の間の一般的な混乱の違いを理解していないことにあると思うので、私はこれをかなり長く書きました。また、これは再帰のみを明示しているわけではないことに注意してください。
C# では、参照型は既定で値渡しされます。多くの人が参照型を参照渡しと混同することがありますが、重要な違いがあります。わかりやすくするために、参照型をそのまま参照し、ref
orout
キーワードを使用して参照渡しします。
参照型を値で渡すと、メモリ内の格納場所への参照であるため、変更を加えて永続化できます。この例を見てください。
public class MyRefType
{
public int Value { get; set; }
}
public void Foo() {
MyRefType type = new MyRefType();
AddOne(type);
}
public void AddOne(MyRefType type) {
type.Value++;
}
ここで何が起こるかというと、クラスtype
の値が 1 になるということです。これが参照型の性質です。の場合、オブジェクトへの参照を保持する代わりにコピーtype
がstruct
作成されるため、Foo メソッド内の値は 0 のままです。
参照型を値で渡すことの意味を理解していただければ幸いです。実際に、参照型を参照で渡すことについて話しましょう。これは、out
andref
キーワードを使用して行います。out
CLR では、技術的には存在せず、存在するだけであることにすぐに注意してくださいref
。out
実際にはref
、特別な属性が適用されたものとしてメタデータで表され、それらは同じように扱われるべきです。
AddOne
ここで、追加を行う前に、メソッドで参照型を再割り当てしたいとしましょう。
public class MyRefType
{
public int Value { get; set; }
}
public void Foo() {
MyRefType type = new MyRefType();
AddOne(type);
}
public void AddOne(MyRefType type) {
type = new MyReferenceType();
type.Value++;
}
まだ参照型を値で渡しているためtype
、メソッド内のの値はFoo
0 のままです。元の格納場所を再割り当てする代わりに、メモリ内の別の格納場所を初期化しただけです)。しかし、実際には参照型を参照渡ししたいので、実際に行う必要があります。
public class MyRefType
{
public int Value { get; set; }
}
public void Foo() {
MyRefType type = new MyRefType();
AddOne(ref type);
}
public void AddOne(ref MyRefType type) {
type = new MyReferenceType();
type.Value++;
}
type
これで、メソッド内のの値はFoo
1 になります。これは、メモリ内に新しい場所を作成する代わりに、参照が指している同じ保存場所を再利用したためです。
では、これはどのように適用されout
ますか? これは、使用法が異なる場合out
と同じであることを忘れないでください。ref
違いは、ref
では参照を初期化せずにメソッドを終了できるのに対し、out
ではメソッドが戻る前に明示的に初期化する必要があることです。
したがって、out
ここで使用する場合、既存の参照シマンティクスが既に機能しているため、まったく必要ありません。これが少し解消されることを願っています。