Kobarin's Development Blog

C#やASP.NET、公開APIなどについての記録です。

C#ジェネリックで、クラスを動的配列化!

メモ程度に書いた記事がブクマされていたので、少し解説を加えたいと思います。

クラスをジェネリック(List)化する理由

ListはGridviewやRepeaterコントロールのDataSouceとしても使用できるため、
一般的によく使われるDataTableよりも、データ生成時点でバグをかなり減らせると考えます。
DataTableは定義もレコード追加も簡単な反面、例えば以下の様なミスが発生してもコンパイル時には検出できません。

DataTable dt = new DataTable();
dt.Columns.Add("name", Type.GetType("System.String"));
dt.Columns.Add("price", Type.GetType("System.Int32"));
dt.Rows.Add("りんご", "100円");  //数字だからって「円」入れちゃダメ
GridView1.DataSource = dt;
GridView1.DataBind(); //←ここで初めて実行時エラー発生

下記のようにList化する事により、データ違いに関してはコンパイル時に全て判明します。
実際当方の某サイトでDataTableをListに置き換えた結果、ソースデータに起因するバグはほぼ根絶できました(同サイトではListViewやGridviewを使用)。

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class generictest : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    System.Collections.Generic.List products = new List();
    
    products.Add(new Product("りんご", 250, 95));   //商品レコードを追加
    products.Add(new Product("みかん", 150, 60));
    products.Add(new Product("ぶどう", 200, 120));

    ListView1.DataSource = products;
    ListView1.DataBind();
  }

  /// 
  /// 商品クラス
  /// 
  protected class Product
  {
    public Product(string name, float weight, int price)
    {
      Name = name;
      Weight = weight;
      Price = price;
    }

    public string Name { get; set; }
    public float Weight { get; set; }
    public int Price { get; set; }
  }
}