1. ホーム
  2. c#

[解決済み】オブジェクトを渡すときに'ref'キーワードを使用するのはなぜですか?

2022-03-26 02:44:44

質問

オブジェクトをメソッドに渡す場合、なぜ ref キーワードを使用しなければならないのですか?いずれにせよ、これはデフォルトの動作ではないのでしょうか?

例えば

class Program
{
    static void Main(string[] args)
    {
        TestRef t = new TestRef();
        t.Something = "Foo";

        DoSomething(t);
        Console.WriteLine(t.Something);
    }

    static public void DoSomething(TestRef t)
    {
        t.Something = "Bar";
    }
}


public class TestRef
{
    public string Something { get; set; }
}

出力は "Bar" で、これはオブジェクトが参照として渡されたことを意味します。

どのように解決するのですか?

を渡す。 ref オブジェクトが何であるかを変更したい場合。

TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(ref t);

void DoSomething(ref TestRef t)
{
  t = new TestRef();
  t.Something = "Not just a changed t, but a completely different TestRef object";
}

DoSomethingを呼び出した後。 t は、元の new TestRef というように、全く別のオブジェクトを指しています。

この方法は、例えば、不変のオブジェクトの値を変更したい場合にも便利です。 string . の値を変更することはできません。 string は、一度作成された後、それが しかし ref のように、文字列を別の値に変更する関数を作成することができます。

を使用するのは ref が必要です。使用方法 ref は、引数を他のものに変更する自由をメソッドに与えます。メソッドの呼び出し側は、この可能性を確実に処理するようにコード化する必要があります。

また、パラメータの型がオブジェクトである場合、オブジェクト変数は常にオブジェクトへの参照として動作します。つまり ref キーワードを使用すると、参照への参照を得たことになります。これにより、上記の例で説明したようなことができるようになります。しかし、パラメータの型がプリミティブな値である場合(例えば int ) の場合、このパラメータをメソッド内で代入すると、メソッドが戻った後に渡された引数の値が変更されることになります。

int x = 1;
Change(ref x);
Debug.Assert(x == 5);
WillNotChange(x);
Debug.Assert(x == 5); // Note: x doesn't become 10

void Change(ref int x)
{
  x = 5;
}

void WillNotChange(int x)
{
  x = 10;
}