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

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

新規登録して質問してみよう
ただいま回答率
85.47%
C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

418閲覧

C#:ジェネリックサンプルコードについて

YuMo_tea

総合スコア17

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2019/02/07 05:20

編集2020/02/26 02:47

前提・実現したいこと

MicroSoft Docsのジェネリックの概要 
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/generics/introduction-to-generics
に記載されているサンプルコードを理解したい

発生している問題・エラーメッセージ

該当ページのサンプルコードのNodeクラスの下にある
private Node head;
が何を指し示しているのかがわかりません。
変数宣言だと思うのですが、なぜ入れ子のNodeが出てくるのでしょうか?
C#は初めて1年未満で、ここ最近ジェネリックを勉強し始めたレベルです。

該当のソースコード

public class GenericList<T> { private class Node { public Node(T t) { next = null; data = t; } private Node next; public Node Next { get { return next; } set { next = value; } } private T data; public T Data { get { return data; } set { data = value; } } } private Node head; public GenericList() { head = null; } public void AddHead(T t) { Node n = new Node(t); n.Next = head; head = n; } public IEnumerator<T> GetEnumerator() { Node current = head; while (current != null) { yield return current.Data; current = current.Next; } } }

試したこと

GenericListのコンストラクタで
head=1と書き換えたところ、先程のprivate Node head;
がprivate int head; になることは確認しました。
1=intでそこが書き換わるのはわかるのですが、nullだとNodeで宣言できるのはどうしてだろう?と悩んでいます。

補足情報(FW/ツールのバージョンなど)

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

このコードにはGenericList<T>クラス内でNodeクラスを定義するNested typeが宣言されているので、これを折りたたんで隠してしまうと、ごくごく普通のクラス宣言でしかないように見えてきませんか?

csharp

1// type parameter T in angle brackets 2public class GenericList<T> 3{ 4 private Node head; 5 6 // constructor 7 public GenericList() 8 { 9 head = null; 10 } 11 12 // T as method parameter type: 13 public void AddHead(T t) 14 { 15 Node n = new Node(t); 16 n.Next = head; 17 head = n; 18 } 19 20 public IEnumerator<T> GetEnumerator() 21 { 22 Node current = head; 23 24 while (current != null) 25 { 26 yield return current.Data; 27 current = current.Next; 28 } 29 } 30}

投稿2019/02/07 05:28

tamoto

総合スコア4119

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YuMo_tea

2019/02/07 07:22

回答ありがとうございます。一旦閉じてみるのは予想外でした。とてもわかりやすく、助かります。 よろしければもう一つお尋ねしてもよろしいでしょうか? private Node head; がクラス宣言ということなのですが、クラス宣言の意味というものがいまいち掴みきれていません。 今はNested Type(入れ子)のNodeクラスは、折りたたんだ箇所で既に宣言と定義が済んでいるという認識です。 その認識なのでprivate Node head; で普通のクラス宣言している、というのがわからないのです。すみません。 (いらない情報かもしれませんが、head に Node のプロパティとフィールドが入ることをステップ実行で確認しています。)
tamoto

2019/02/07 07:29

いえいえいえいえ、`private Node head;` はプライベートフィールド変数の宣言です、入れ子クラス宣言はその上の`private class Node { ... }`のことです(回答に記載したコードはこれを隠した(削除した)ものです) 単に、`Node`という名前の「別の」クラスが存在していて、`GenericList<T>`の中にその`Node`を一つ入れるフィールド変数を用意した、というだけと考えてみてください。
YuMo_tea

2019/02/07 07:36

再度回答ありがとうございます。 なるほど、そういうことだったのですね。すごく引っかかてしまった箇所なので、本当に助かりました。 初歩的な質問にもかかわらず、丁寧に解説していただきありがとうございました。 全て一括で見てしまう癖があるのでしっかり理解できるよう、頂いた回答を参考にしていきます。
guest

0

private Node head;

が何を指し示しているのかがわかりません。

NodeはGenericListの__Generic__ではなくListのために用意されたものです。
Nodeインナークラスをなぜ作ったかを考えるにはまず、LinkedListのデータ構造を理解する必要があると思います。

GenericListのコンストラクタで

head=1と書き換えたところ、先程のprivate Node head;
がprivate int head; になることは確認しました。

csharp

1 // constructor 2 public GenericList() 3 { 4 head = 1; 5 }

こうしたということですか?エラーになりませんか?仮にhead = new Node(1);としても、private int headにはなりません。そうしたとしてもprivate Node headですし、間違っていますが、あえていえばNode<int> headです。
内包するものの型が何でも受けて、数珠つなぎができるように用意されたのが非ジェネリックなNodeクラスです

1=intでそこが書き換わるのはわかるのですが、nullだとNodeで宣言できるのはどうしてだろう?と考えてしまいます

headに何を代入しても、NodeはNode型のままで、Nodeは参照型(class)なのでdefault(Node)であるnullを代入可能です

投稿2019/02/07 07:37

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YuMo_tea

2019/02/08 08:38 編集

回答ありがとうございます。 エラー部分の解説までしていただき助かりました。 02/08追記 LinkedList・双方向連結リストについても学習できるきっかけになりました。再度になりますが、ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問