質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • C#

    6555questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C#における参照型の代入の振る舞いについて

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 165

hiro_j3cub

score 1

当方、C#にて趣味プログラマーをしております。
今回、C#における参照型の振舞いについて、質問させていただきます。

開発環境 : Microsoft Visual Studio Community 2015

試したこと

参照型への代入について調べるため、下記のテストコードを実行しました。

    class Program
    {
        static void Main(string[] args)
        {
            MyClass a = new MyClass("A");
            MyClass b = new MyClass("B");
            MyClass c = new MyClass("C");

            a = c;
            c = b;

            Console.WriteLine("a = " + a.Name);
            Console.WriteLine("b = " + b.Name);
            Console.WriteLine("c = " + c.Name);

            Console.ReadKey();
        }
    }

    class MyClass
    {
        public string Name { get; private set; }

        public MyClass(string name)
        {
            Name = name;
        }
    }


結果は、

a = C
b = B
c = B


となりました。

たとえば、b=a;c=b;としたときに、bにはaへの参照が、cにはbの参照が入るため、
中身はすべて"A"になるので、
上記テストコードの場合、a=cでaにはcへの参照が、c=bでcにはbへの参照が入るため、
中身はすべて”B”になるのでは?と思いました。
しかし実際には、aの中身は"C"でした。

質問内容

上記のような事が起きる理由・仕組みを知りたいです。

初歩的な質問かもしれませんが、よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

a,b,cにそれぞれ最初に代入したオブジェクトのリファレンスをそれぞれr1,r2,r3とすると・・・

a = cとしたとき、aはcを指すと考えるのではなくaにその時点でcに入っていた値(r3というオブジェクトへの参照)が代入されるだけですので、aがcを指すという表現は混乱を招きます。

WriteLineの実行時点ではaにr3、cにr2が入っていますのでご質問のような結果になります。r1~r3の参照をどの変数へ代入しようがa~cがr1~r3のどれを指すかが変化するだけと考えると振る舞いが把握できるのではないでしょうか?

         r3
c -----> +------+
         |Name ---> "C"
         +------+

cをaに代入するとcとaが同じオブジェクトを指すようになるだけ

a --+    r3
c --+--> +------+
         |Name ---> "C"
         +------+

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/02 19:15

    つまり、a=cは、c自体を参照するのではなく、cが指すオブジェクトを参照すると言う事だったんですね。
    理解できました!
    丁寧なご回答、ありがとうございました。

    キャンセル

+2

こんにちは。

たとえば、b=a;c=b;としたときに、bにはaへの参照が、cにはbの参照が入るため、

それは違います。
C#の参照は要するにC言語のポインタとほぼ同じものです。
つまり、a=c;によりcが指していたオブジェクトへの参照がaに設定されます。
代入前cにはnew MyClass("C")にて生成されたオブジェクトへの参照が入ってましたから、代入後aにはnew MyClass("C")にて生成されたオブジェクトへの参照が設定されます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/02 19:04

    なるほど・・・。
    つまり、b=a;とした時も、bには、a ではなく、 new MyClass("A") で生成されたオブジェクトへの参照が入ってたんですね。
    どうやら自分は変数とオブジェクトをごっちゃにして考えていたみたいです。
    ご回答ありがとうございました。

    キャンセル

  • 2017/10/02 21:24

    回答を書く手が遅くChironianさんより大分後の回答でした。
    BAが自分の回答につきましたが、Chironianさんの回答との違いはほぼなく、同じような回答を付けてしまったことを申し訳なく思います。
    >Chironianさん、質問者さん

    キャンセル

  • 2017/10/02 22:01

    いえいえ、私も良くやっちゃいますし、問題ないですよ。内容もより親切ですし。

    キャンセル

  • 2017/10/02 22:34 編集

    お二方の回答は、どちらも自分の分からなかった部分を的確に指摘してくださっており、大変参考になりました。
    BAに関しては、自分がより分かりやすいと感じたKSwordOfHasteさんの回答にさせていただきました。
    お二方とも、改めて、ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    6555questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。