C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: Listの入れ子について


(過去ログ 55 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■30801 / inTopicNo.1)  Listの入れ子について
  
□投稿者/ めろぱん (10回)-(2009/01/07(Wed) 00:44:46)

分類:[C#] 

開発環境:Visual Studio 2008
言語:Visual C#

こんばんは、めろぱんと申します。

皆さんはListを入れ子にして使ったことはありますでしょうか?
例えば、
List<List<String>> nameList = new List<List<String>>();
こんな感じです。

StringのListをいくつか作り、それをまたListでひとまとめにして
しまいたいと考え、上記のようにしましたが、
これだとVisual Studioのコード分析で怒られてしまいます。

「CA1006:ジェネリック型をメンバ シグネチャ内で入れ子にしません」
http://msdn.microsoft.com/ja-jp/library/ms182144.aspx

警告を無視できない事情もあり、修正をしたいと考えています。
MSDNではもっと分かりやすい構造に見直しなさい、
みたいなことが書いてあり、いろいろ考えてみましたが、
良い策が見つけられておりません。
皆さんならどのように修正をしますでしょうか?
知恵をお借りしたく存じます。

なお、Listを入れ子にした理由ですが、
ある学校の生徒を成績で3グループに分けます。
この1グループがList<String>になり、
ここに生徒の氏名を入れていきます。
入れ終わったら、氏名でソートします。
そしてこの3つのList<String>を決められた成績順で
List<List<String>>につっこんでいくと、
成績順かつ氏名順で取り出せる、
ということをやりたかったためです。

よろしくお願いします。
引用返信 編集キー/
■30810 / inTopicNo.2)  Re[1]: Listの入れ子について
□投稿者/ まさる (44回)-(2009/01/07(Wed) 09:56:30)
まさる さんの Web サイト
普通にList<List<string>>を使えましたけど。

■コード
class Program
{
  static void Main(string[] args)
  {
    var listList = new List<List<string>>();

    for ( var i = 0; i < 3; i++ )
    {
      var list = new List<string>();
      for ( var j = 0; j < 3; j++ )
      {
        list.Add(String.Format("{0}{1}", i, j));
      }
      listList.Add(list);
    }

    listList.ForEach(list => list.ForEach(Console.WriteLine));

    Console.ReadKey();
  }
}

■実行結果
00
01
02
10
11
12
20
21
22

引用返信 編集キー/
■30811 / inTopicNo.3)  Re[1]: Listの入れ子について
□投稿者/ こくぶん (2回)-(2009/01/07(Wed) 10:00:38)
こくぶん さんの Web サイト
No30801 (めろぱん さん) に返信
> なお、Listを入れ子にした理由ですが、
> ある学校の生徒を成績で3グループに分けます。
> この1グループがList<String>になり、
> ここに生徒の氏名を入れていきます。
> 入れ終わったら、氏名でソートします。
> そしてこの3つのList<String>を決められた成績順で
> List<List<String>>につっこんでいくと、
> 成績順かつ氏名順で取り出せる、
> ということをやりたかったためです。

グループの数が決まっているなら、外側はList<String>の配列じゃダメなのでしょうか?


# 「ジェネリック型を入れ子にするとコード解析で警告が出る」と云う事を今まで知りませんでした。
# とても勉強になりました。


No30810 (まさる さん) に返信
使えるけどコード解析すると警告が出る、と云う事だと思います。
ってか私も今まで気にせずに使ってました。。。

引用返信 編集キー/
■30812 / inTopicNo.4)  Re[2]: Listの入れ子について
□投稿者/ まさる (45回)-(2009/01/07(Wed) 10:08:43)
まさる さんの Web サイト
No30811 (こくぶん さん) に返信
> ■No30810 (まさる さん) に返信
> 使えるけどコード解析すると警告が出る、と云う事だと思います。
> ってか私も今まで気にせずに使ってました。。。

改めて警告を確認してみたところ、「メンバ シグネチャ内で入れ子にしません」なので、
「引数、戻り値の型に入れ子になったジェネリック型を使えない」
ということみたいですね。

なので、私の回答は見当はずれということで(^^;

解決するには、List<string>を引数(だと思うんですが)とするメソッドを定義して、
List<List<string>>をforeachで回して上記のメソッドを呼ぶようにすることで、
一応回避は出来そうな気がします。
引用返信 編集キー/
■30818 / inTopicNo.5)  Re[1]: Listの入れ子について
□投稿者/ も (66回)-(2009/01/07(Wed) 10:56:16)
No30801 (めろぱん さん) に返信
試してないけどなんとなく。
class hoge : List<string>> { } して List<hoge> とかだとどうなるだろう。
引用返信 編集キー/
■30821 / inTopicNo.6)  Re[1]: Listの入れ子について
□投稿者/ επιστημη (1486回)-(2009/01/07(Wed) 11:27:08)
επιστημη さんの Web サイト
> 警告を無視できない事情もあり、修正をしたいと考えています。

現在のコードが(おそらく)最良と思われるのであれば、
警告を潰すだけのために変にねじまげるのは下策です。

# error/warningを潰すためにむやみにキャストかますのと同様

引用返信 編集キー/
■30823 / inTopicNo.7)  Re[2]: Listの入れ子について
□投稿者/ aetos (65回)-(2009/01/07(Wed) 12:07:18)
No30821 (επιστημη さん) に返信
>>警告を無視できない事情もあり、修正をしたいと考えています。
>
> 現在のコードが(おそらく)最良と思われるのであれば、
> 警告を潰すだけのために変にねじまげるのは下策です。
>
> # error/warningを潰すためにむやみにキャストかますのと同様

現在のコードが(おそらく)最良と思われるのであれば、
SuppressMessageAttribute で黙らせることができます。
引用返信 編集キー/
■30826 / inTopicNo.8)  Re[3]: Listの入れ子について
□投稿者/ biac (9回)-(2009/01/07(Wed) 13:52:10)
biac さんの Web サイト
No30823 (aetos さん) に返信
> 現在のコードが(おそらく)最良と思われるのであれば、
> SuppressMessageAttribute で黙らせることができます。

まったくもって、そのとおり。

…なんですが、 この 1年ほど見てきた経験からすると、 ジェネリック型をメンバシグネ
チャ内で入れ子にしているコードのたいていは、 理解しにくいしメンテしにくいように
感じています。

> MSDNではもっと分かりやすい構造に見直しなさい

…というのは、 List<List<String>> nameList という宣言部分に限ったことではなくて、
プログラム全体の構造も見直してみてはどうでしょう、 と理解した方がいいと思います。

めろぱんさんの欲しいモノは、 リストの各要素にリストを持っているという構造をした
モノ、 というよりは、 ひょっとしたら、 自由に並び替えの出来る 「成績一覧表」 
みたいなモノじゃないでしょうか?
もしそうなら、 List<List<String>> よりも例えば DataTable のほうが、 欲しいモノに
近いかもしれません。

using System;
using System.Data;
namespace 成績一覧{
	class Program{
		static void Main(string[] args){
			using (DataTable 成績表 = 成績表準備()){

				生徒氏名と成績をセットする(成績表);

				// 成績表を投影するビューを作り…
				using (DataView 成績表ビュー = 成績表.AsDataView()){
					// ソートして…
					成績表ビュー.Sort = "成績 ASC, 生徒氏名 ASC";

					出力する(成績表ビュー);
				}

				キー入力待ち();
			}
		}

		private static DataTable 成績表準備() {
			DataTable dt = new DataTable("成績表");
			dt.Columns.Add("成績", typeof(string));
			dt.Columns.Add("生徒氏名", typeof(string));

			return dt;
		}

		private static void 生徒氏名と成績をセットする(DataTable 成績表) {
			成績表.Rows.Add("B", "たなか いちろう");
			成績表.Rows.Add("A", "なかむら くにお");
			成績表.Rows.Add("C", "あいざわ こうへい");
			成績表.Rows.Add("B", "かとう もとこ");
			成績表.Rows.Add("C", "さいとう みき");
			成績表.Rows.Add("A", "はせがわ きょうこ");
		}

		private static void 出力する(DataView dv) {
			Console.WriteLine(dv.Table.TableName);
			foreach (DataRowView r in dv){
				Console.Write(r["成績"]);
				Console.Write(" ");
				Console.WriteLine(r["生徒氏名"]);
			}
		}

		private static void キー入力待ち(){
			Console.Write("何かキーを押すと、 プログラムを終了します。");
			Console.ReadKey();
		}
	}
}

[実行結果]
成績表
A なかむら くにお
A はせがわ きょうこ
B かとう もとこ
B たなか いちろう
C あいざわ こうへい
C さいとう みき
何かキーを押すと、 プログラムを終了します。

引用返信 編集キー/
■30827 / inTopicNo.9)  Re[1]: Listの入れ子について
□投稿者/ επιστημη (1487回)-(2009/01/07(Wed) 14:09:19)
επιστημη さんの Web サイト
2009/01/07(Wed) 14:33:55 編集(投稿者)
> なお、Listを入れ子にした理由ですが、
> ある学校の生徒を成績で3グループに分けます。
> この1グループがList<String>になり、
> ここに生徒の氏名を入れていきます。
> 入れ終わったら、氏名でソートします。
> そしてこの3つのList<String>を決められた成績順で
> List<List<String>>につっこんでいくと、
> 成績順かつ氏名順で取り出せる、
> ということをやりたかったためです。

僕なら成績と氏名をメンバに持つ

class レコード { public int 成績; public string 氏名; }
を LinkedList<レコード> にぶちこみます。
# 総数が既知なら レコード[] で十分。

んでもって成績と氏名をキー(大小判定基準)としてソートしますが。

using System;

class レコード { 
  public int 成績; 
  public string 氏名; 
  public レコード(int score, string name) 
    { 成績 = score; 氏名 = name; }
  public static int レコード比較(レコード x, レコード y) {
    int result = x.成績.CompareTo(y.成績);
    return result == 0 ? x.氏名.CompareTo(y.氏名) : result;
  }

  public static void Main() {
    レコード[] 成績表 = {
      new レコード(2, "たなか いちろう"),
      new レコード(1, "なかむら くにお"),
      new レコード(3, "あいざわ こうへい"),
      new レコード(2, "かとう もとこ"),
      new レコード(3, "さいとう みき"),
      new レコード(1, "はせがわ きょうこ")
    };
    Array.Sort(成績表, レコード比較);
    foreach ( レコード rec in 成績表 ) {
      Console.WriteLine("{0} {1}", rec.成績, rec.氏名);
    }
  }
}

引用返信 編集キー/
■30970 / inTopicNo.10)  Re[2]: Listの入れ子について
□投稿者/ めろぱん (12回)-(2009/01/10(Sat) 00:41:33)
返事が遅くなりすみません。
皆様、たくさんのご意見ありがとうございました。

新たなクラスを作って対応するか、
現状のコードがよいと考えるならそのままとする
(警告を黙らせる)か、
というご意見かと思います。

新たなクラスをつくらず.NETのクラスでまかないたく、
現状のままとしたい、というのが本音です。
また、サンプルコードをご提示いただきましたが、
ある成績のグループのリストだけを取得したい、
というのもあり、
リストのリスト、という構造がやっぱり良いのかなぁと
考えています。
(サンプルコード自体は参考になりました。ありがとうございます)

ここではひとまず、現状のコードで進めるということで解決にしたいと
思います。
最終的に別の策をとった時には、ここでご報告をしたいと思います。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -