8
class Test
{
    static void Func(StringBuilder myString)
    {
        myString.Append ("test");
        myString = null;
    }
    static void Main()
    {
        StringBuilder s1 = new StringBuilder();
        Func(s1);
        Console.WriteLine (s1);
    }
}

出力は「Test」ですが、null ではないのはなぜですか?

s1 がFunc() への参照によって渡される場合、なぜmyString.Append("test")変更しないのに変更myString = nullしないのでしょうか?

前もって感謝します。

4

5 に答える 5

12

オブジェクトへの参照を値で渡しています。

つまり、オブジェクトのアドレスは値で渡されますが、オブジェクトへのアドレスとオブジェクトは同じです。したがって、メソッドを呼び出すと、VM は参照をコピーします。コピーを変更しているだけです。

myString.Appendコピーされた参照を使用してオブジェクト (まだ 1 つのオブジェクトのみ) を取得し、それを変更/呼び出します。

あなたがしていると思うことはこれです:

class Test
{
    static void Func(ref StringBuilder myString)
    {
        myString.Append("test");
        myString = null;
    }
    static void Main(string[] args)
    {
        StringBuilder s1 = new StringBuilder();
        Func(ref s1);
        Console.WriteLine(s1);
    }
}

より長い説明: http://javadude.com/articles/passbyvalue.htm

于 2013-09-13T13:29:22.737 に答える
10

s1 が Func() への参照によって渡される場合、なぜ myString.Append("test") はそれを変更するのですか?

参照渡しではなく、アドレス値が関数に渡されます。

がメモリ位置0x48S1を指しているとします。これは に渡されFuncFuncパラメータmyStringはその位置を指し始めます。後でAppendその場所にテキストを送信すると、追加されます。ただし、後で に割り当てるnullmyString、何も指しなくなりますが、元の場所は変更されません。

Jon Skeetによる C# でのパラメーターの受け渡し

次の図を検討してください。ステップ 1 では、型の新しいオブジェクトを作成し、そのオブジェクトStringBuilderを letS1で参照します。

ここに画像の説明を入力

ステップ 2 で に渡しS1た後FuncmyStringもメモリ内の同じオブジェクトを指します。

ここに画像の説明を入力

後でAppend、テキストを介して、オブジェクトが保持するメモリ位置を指しているmyStringため、元のオブジェクトを更新します。myString

ステップ 3 で、 null を に割り当てると、 objectmyStringのアドレスが失われStringBuilderますが、これは object または pointer の何も変更しませんS1

ここに画像の説明を入力

于 2013-09-13T13:31:38.640 に答える
2

C# では、既定では、複合型へのポインター (参照) は値によって渡されます。次のように、参照渡しであることを指定する必要があります。

static void Func(ref StringBuilder myString)
{
    myString.Append ("test");
    myString = null;
}
于 2013-09-13T13:30:49.337 に答える
0

StringBuilder s1 への参照を Func に渡すためです。Func 内では、同じ StringBuilder インスタンスへの参照は「myString」と呼ばれます。最初に何かを行うように指示し (" myString.Append("Test"))、参照 INSIDE Func を null に設定します。Append の結果は Main() に表示されます。null に設定されている参照は Main の s1 に影響しません。

于 2013-09-13T13:33:22.460 に答える
0

関数に を追加しrefて、ref で渡します。

static void Func(ref StringBuilder myString)
{
    myString.Append ("test");
    myString = null;
}

次に、次のように呼び出します。

Func(ref s1);
于 2013-09-13T13:30:33.807 に答える