7

今日は値型と参照型について学びました。

以下のコードサンプルに1つ疑問があります。

class Program
{
    static void Main(string[] args)
    {
        StringBuilder sb = new StringBuilder();
        FunctionSB(sb);
        Console.WriteLine(sb); //sb updated

        customer c = new customer();
        FunctionClass(c);
        Console.WriteLine(c.s);//updated class value 

        String str = "";
        FuntionString(str);
        Console.WriteLine(str);//

    }

    private static void FunctionSB(StringBuilder sb)
    {
        sb.Append("sb updated");
    }

    private static void FunctionClass(customer c)
    {
        c.s = "updated class value ";
    }

    static void FuntionString(String str)
    {
        str = "updated value";
    }
}
class customer
{
    public string s;
}

ここでは、文字列ビルダーの値とクラス メンバー変数の値が更新されていますが、値が更新されていないのはなぜFuntionString(str);ですかstr? (参照として渡されないのはなぜですか?)

4

4 に答える 4

4

認識すべきことは、 を記述するとき、str = "updated value";実際には新しいオブジェクトを作成していることです。つまり、次と同等のことを行いました。

str = new string("updated value");

これは、 を記述するときにstr = "updated value"、既存のオブジェクトを変更するのではなく、参照 "str" に新しいオブジェクトを割り当てることを意味します。**

したがって、「顧客」クラスに関する正しい比較ポイントは次のとおりではありません。

c.s = "updated class value";

むしろ:

c = new customer { s = "updated class value" }.

したがって、「c」または「str」によって以前に保持されていた参照によって指されている元のオブジェクトは変更されません。


OP の場合に必要なことは、次のrefキーワードを使用して文字列への参照を渡すことです。

static void FuntionString(ref String str)
{
    str = "updated value";
}

ここでの違いは、参照自体が 内FunctionStringで更新され、新しい文字列オブジェクトを指すようになったことです。


** . Net 文字列は不変であるため、これは常に true になることに注意してください。文字列オブジェクトを変更することはできません。新しいオブジェクトを作成して再割り当てするだけです。これを少し別の言い方で言い直すと、はい、文字列は参照によって渡されますが、文字列型は不変であるため、その参照を使用してオブジェクトを変更することはできません。

于 2013-10-09T18:27:53.477 に答える
0

C# の文字列は組み込みのデータ型です。値を渡して再参照できるようにしたい場合 (変更不可、置換のみ、文字列は不変)、 out 修飾子が必要です。

    static void FuntionString(out String str) 
    {
        str = "updated value";
    }

これは、基本的に参照渡しと同じです。唯一の違いは、out を使用する場合、文字列を初期化する必要があることです。これが確実でない場合は、代わりに ref を使用してください。

于 2013-10-09T18:25:48.910 に答える