2

私はこのトリッキーな問題に遭遇しました。次のコードを参照してください。

public class Foo
    public int A { get; set; }
}

static void Main(string[] args)
{
    Foo foo1 = new Foo();
    Foo foo2 = new Foo();

    ChangeObject1(foo1);
    ChangeObject2(ref foo2);

    Console.WriteLine("Foo1 = " + foo1.A);
    Console.WriteLine("Foo2 = " + foo2.A);
    Console.ReadKey();
}

static void ChangeObject1(Foo foo)
{
    foo.A += 1;
    foo = new Foo();
}

static void ChangeObject2(ref Foo foo)
{
    foo.A += 1;
    foo = new Foo();
}

いくつかのテストの後、foo1.Aは1に等しく、foo2.Aはまだ0に等しいです。私の理解では、これは2番目のメソッドが値ではなく参照によって渡されるインスタンスを持っているためです。これによりインスタンスのコンテンツが変更されるため、メソッドで新しいオブジェクトが作成および割り当てられると、値は定義されなくなります。

しかし、インスタンスのコンテンツがメソッドの外部で変更されているため、値が渡されたとしても、最初のメソッドでも同様の効果があるはずだと思うので、それについて考えると混乱します。

誰かが実際に何が起こっているのか知っていますか?ありがとう!

4

2 に答える 2

3

C# または Java を使用していると思います。いずれにしてもコンセプトは変わらない

foo 変数を宣言するとき

Foo foo1 = new Foo()

参照型と呼ばれるものを宣言しています。(クラスを表すすべてのオブジェクトは参照型です)

したがって、に格納されている値は実際には でfoo1はありませんがFoo、そのメモリ アドレスを保持する値ですFoo

あなたが電話するとき

    static void ChangeObject1(Foo foo)
    {
        foo.A += 1;
        foo = new Foo();
    }

その参照のコピーを渡しています。したがって、これを行うfoo.A += 1と、渡したばかりのオブジェクトのメンバー値が変更されます。

その場合foo = new Foo(); 、参照のコピーを変更するだけで、元のオブジェクト参照自体は変更しません。

今、あなたが電話するとき

    static void ChangeObject2(ref Foo foo)
    {
        foo.A += 1;
        foo = new Foo();
    }

あなたはあなたのアドレスのコピーを渡していませんが、あなたのFooアドレスのアドレスを渡していますFoo.

Foo元のアドレス自体を渡しているかのように考えることができます。

したがって、 を呼び出すときfoo = new Foo()、その前に foo に何をしたかは問題ではありません。アドレスを新しいFooオブジェクトのアドレスで上書きしました。

メソッドを次のように変更した場合

    static void ChangeObject2(ref Foo foo)
    {
        foo.A += 1;
    }

その後、変更に気付くはずです

参照型を説明しているページはこちら Javaで書いていますが、同じ原理がc#にも当てはまります

于 2012-09-11T18:31:44.577 に答える
-1

おそらく、参照型ではなく値型の観点から考えると役立つでしょう。最初の例を見てください(括弧内の数字は整数値を保持するメモリアドレスを表します)。

値渡し

[0001] -> 5;

値を渡すと、値5が新しいメモリアドレスにコピーされます

[0002] -> 5;    
[0002] -> 10;    // changes the value of a new reference

[0002]の値を変更しても、[0001]には影響しません。


参照による通過

[0001] -> 5;

一方、アドレス自体を渡す場合(refキーワードを使用して渡す)

[0001] -> 5;    
[0001] -> 10;    // changes the value of the original reference

これで、参照が保持している値を変更できます。


整数を保持する代わりに参照型は、オブジェクトへのアドレスを保持します。したがって、参照を渡す場合は、値を保持する「コンテナ」(つまり、ポインタ/参照)を渡すことになります。次に、コンテナが保持するものを変更できます。値を渡す場合は、コンテナーから値を取り出して渡すことになり、元のコンテナーは画像から外れます。

于 2012-09-12T05:34:54.067 に答える