C#2.0で追加された主な機能です。

目次

ジェネリック

  • ジェネリックにより、特定の型に依存しない汎用的なクラス、構造体、メソッド、インターフェイス、デリゲートが作成可能
  • <>で型パラメータを宣言し、使用する側でも<>で型指定をする
  • whereキーワードにて型パラメータを制限することが可能
  • ArrayListで必要であったキャストが不要
  • コレクションへの追加時ボックス化は行われないため高速
public class GenericSample
{
  static void Main()
  {
    //int型のコレクションを生成
    GenericList<int> intList = new GenericList<int>();      
    intList.Add(1);
    //double型のコレクションを作成
    GenericList<double> dblList = new GenericList<double>();    
    dblList.Add(1.1);
  }
}
//特定の型に依存しない汎用的なクラス
public class GenericList<T>
{
  public void Add(T item)
  {
  }
}
 

部分クラス

  • 部分クラスにより、クラス、構造体、インターフェイスを複数のソースファイルに分割が可能
  • 分割するにはpartial修飾子を使用する
  • 複数のプログラマで同一クラスを同時に編集する場合や、プログラマに直接編集されたくない部分を分ける場合などに利用する
  • WindowsアプリケーションのWindowsフォームでは、以下のように部分クラスが使用されている
//プログラマが編集する部分クラス、ファイル名はForm1.cs
public partial class Form1 : Form
{
  public Form1()
  {
    InitializeComponent();
  }
}
 
//フォームデザイナが自動的に更新する部分クラス、ファイル名はForm1.Designer.cs
partial class Form1
{
  /// <summary>
  /// 必要なデザイナ変数です。
  /// </summary>
  private System.ComponentModel.IContainer components = null;
  ……中略……
}
 

静的クラス

  • System.Mathクラスのように、静的なメンバのみもつクラスを作成する場合に使用する
  • 静的クラスを宣言するにはstatic修飾子をつける
  • 外部から呼び出されることが前提となるため、アクセス修飾子はpublicのみ使用可
  • インスタンス化は出来ない
  • インスタンスコンストラクタは含むことはできない。静的コンストラクタは含むことが可能
  • 継承は出来ない
  • クラスを含むプログラム、名前空間が読み込まれるとCLRにより自動的に読み込まれる
  • "インスタンス名.メンバ"ではなく"クラス名.メンバ"と記述しメンバにアクセスする
class StaticSample
{
  static void Main(string[] args)
  {
    double maxValue = StaticMath.Max<double>(1.1, 1.2);
  }
}
 
//静的クラス
static class StaticMath
{
  //2つの変数を比較し最大値を返すメソッド
  public static T Max<T>(T a, T b)
    where T : IComparable
  {
    if (a.CompareTo(b) > 0)
    {
      return a;
    }
    else
    {
      return b;
    }
  }
}
 

匿名メソッド

  • 匿名メソッドは、デリゲートインスタンス生成時に埋め込む名前なしのブロックをさす
  • delegateキーワードの後の{・・・}; にメソッドの内容を記述する
  • 外部メソッドを再利用しない場合や、コードをシンプルにしたい場合に使用する
delegate int D(int x, int y);
 
class Program
{
  static void Main(string[] args)
  {
    //匿名メソッド未使用時
    //外部メソッドを用意し登録する必要があった
    D d1 = new D(Add);
 
    //匿名メソッド使用時
    //{・・・}内に直接記述する
    D d2 = delegate(int x, int y)
    {
        return x + y;
    };
 
    Console.WriteLine(d1(1, 2));
    Console.WriteLine(d2(3, 4));
  }
 
  static int Add(int x, int y)
  {
    return x + y;
  }
}
 

プロパティ アクセサのアクセシビリティ

  • プロパティのgetアクセサ、setアクセサにアクセス修飾子の指定が可能となった
  • get、setどちらかのみアクセス修飾子が設定可能
  • get、setのアクセスレベルはプロパティのアクセスレベルより制限されている必要がある
  • 値の取得は他のクラスから可能とし、値の設定はクラス内からのみ行なわせたい場合などに使用する
private string name;
 
public string Name
{
  get
  {
    return name;
  }
  private set
  {
    name = value;
  }
}
 

イテレータ

  • 従来foreach文にて列挙可能なコレクションクラスを作成するには、IEnummerable、IEnumratorのインターフェース2つを実装する必要があり面倒だったが、イテレータにより容易に作成が可能となった
  • IEnumeratorを戻り値とするGetEnumeratorメソッドを追加し、yield returnにて返す値を指定する
  • yield breakにて強制的に列挙を終わりにすることも可能
class Program
{
  static void Main(string[] args)
  {
    Enum1 enum1 = new Enum1();
    foreach (string dayOfWeek in enum1)
    {
      Console.WriteLine(dayOfWeek);
    }
    
    Enum2 enum2 = new Enum2();
    foreach (string dayOfWeek in enum2)
    {
      Console.WriteLine(dayOfWeek);
    }
  }
}
 
//C#1.0 Enummerable、IEnumratorのインターフェース2つを実装する必要がある
public class Enum1 : IEnumerable
{
  public IEnumerator GetEnumerator()
  {
    return new Enumrator1(this);
  }
    public string[] dayOfWeeks = { "Monday ", 
                                   "Tuesday ", 
                                   "Wednesday ", 
                                   "Thursday ", 
                                   "Friday ", 
                                   "Saturday ", 
                                   "Sunday " };
}
 
public class Enumrator1 : IEnumerator
{
  Enum1 m_enum1;
  int m_position;
  public Enumrator1(Enum1 enum1)
  {
    m_enum1 = enum1;
    Reset();
  }
 
  public object Current
  {
    get
    {
      return m_enum1.dayOfWeeks[m_position];
    }
  }
 
  public bool MoveNext()
  {
    if (m_position >= m_enum1.dayOfWeeks.Length - 1)
    {
      return false;
    }
  m_position++;
  return true;
  }
 
  public void Reset()
  {
    m_position = -1;
  }
}
 
//C#2.0 IEnumeratorを戻り値とするGetEnumeratorメソッドを用意するのみでよい
public class Enum2
{
  public string[] dayOfWeeks = { "Monday ", 
                                   "Tuesday ", 
                                   "Wednesday ", 
                                   "Thursday ", 
                                   "Friday ", 
                                   "Saturday ", 
                                   "Sunday " };
 
  public IEnumerator<string> GetEnumerator()
  {
    foreach (string dayOfWeek in dayOfWeeks)
    {
      yield return dayOfWeek;
    }
  }
}
 

null 許容型

  • 従来、値型にはnull値を代入は出来ず、データがない状態を表す場合 -1 などで表す必要があった
    null許容型を使用すると、null の値を割り当てることができる値型の変数を作成できる
  • 構文 T? にてnull許容型を作成する(System.Nullable<T> の省略表現)
  • HasValueプロパティにて値があるか判定可能
  • Valueプロパティにて値を取得可能
  • GetValueOrDefaultメソッドにて、null許容型の値がnullの場合に値型のデフォルト値が取得可能
  • ?? 演算子を使用すると、null許容型の値がnullの場合にデフォルト値が指定可能
static void Main(string[] args)
{
  int? x = null;
 
  if (x.HasValue)
  {
    Console.WriteLine(x.Value);
  }
  else
  {
    Console.WriteLine("xはnullです");
  }
 
  Console.WriteLine(x.GetValueOrDefault()); 
 
  int y = x ?? 0;
}
 

参考
C# 2.0 言語およびコンパイラの新機能
http://msdn.microsoft.com/ja-jp/library/7cz8t42e(VS.80).aspx
最終更新:2009年12月10日 19:21