C# 入門

ホーム > C# の基礎 > 匿名型

匿名型

スポンサーリンク

C# 3.0 から匿名型 (anonymous types) が利用可能になりました。

通常 "データ型" というと int 型とか double 型などと指定するわけですが、それが匿名、名無し、というわけです。

これは一体どういうわけでしょうか。

ここでは C# に新しく導入された匿名型というのがどういうものか、なぜ導入されたか、ということについて説明します。

C# の匿名型とは?

ここでは匿名型とは何か、ということを説明するために、まずは「匿名とか名無し」ではないものを先に確認します。

仮に通常のものを "名有り" とでもいいましょうか。名有りの型 (type) は通常次のようなものです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AnonymousTypesTest1
{
  class Person
  {
    public string Name { get; set; }
    public int Age { get; set; }
  }

  class Program
  {
    static void Main(string[] args)
    {
      Person p = new Person() {
        Name = "Taro Yamada",
        Age = 30
      };

      Console.WriteLine("{0} ({1})", p.Name, p.Age);
    }
  }
}

この実行結果は次の通りです。

Taro Yamada (30)

尚、ここでは後の説明で都合が良いように、オブジェクト初期化子 を利用しています。こうした書き方に不慣れな人は、 「オブジェクト初期化子」の説明をみてください。

さて、ここで定義している Person クラス、すなわち Person型 をみてください。

Person型では、Name と Age という二つのプロパティが定義されています。それぞれ string 型, int 型です。

#中身は { get; set; } しか書いていませんが、これは自動実装プロパティ (Auto-Implemented Properties) ですね。

Main メソッド内で Person オブジェクトを作成し、それのプロパティを設定。そして、コンソールに内容を出力しています。

同様のことを匿名型を用いて実現してみましょう。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AnonymousTypesTest2
{
  class Program
  {
    static void Main(string[] args)
    {
      var p = new {
        Name = "Taro Yamada",
        Age = 30
      };

      Console.WriteLine("{0} ({1})", p.Name, p.Age);
    }
  }
}

この実行結果はやはり次の通りになります。

Taro Yamada (30)

匿名型を利用したのは次の箇所です。

  var p = new {
    Name = "Taro Yamada",
    Age = 30
  };

オブジェクトを作成するために "何か" を new していますが、new の後に型 (クラス) の名前がありません。

冒頭のコードで Person を初期化した場合と比較すると明らかに違いますね。

  Person p = new Person() {
    Name = "Taro Yamada",
    Age = 30
  };

匿名型は暗黙的型指定ローカル変数 var を用いて宣言し、new でオブジェクトを作成します。 このとき型名を指定せずに、その場で { } を用いてプロパティを定義しています。

このように型の定義をあらかじめすることなく(従って名前も付いていない)、利用する型を匿名型といいます。

ちなみに試しに次のようなコードで、匿名型の名前を出力してみると、内部で機械的な名前が付けられていることがわかります。

      Console.WriteLine("{0}", p.GetType().ToString());

結果は次の通り。

<>f__AnonymousType0`2[System.String,System.Int32]

なぜ匿名型?

匿名型はなぜ C# に導入されたのでしょうか。

ひとつには一時的にしか利用しない型を、簡便に定義して使えるようにするため、という意味があります。

もうひとつは、LINQ に対応するためです。

例えば Person 型を定義して、そのコレクションがあったとします。その中から条件によって特定の要素のみを抜き出し、 興味のあるプロパティだけ、結果として取得したいと考えます。

こうした場合の LINQ は次のように記述します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AnonymousTypesTest3
{
  class Program
  {
    class Person
    {
      public int Age { get; set; }
      public string Name { get; set; }
      public string City { get; set; }
    }

    static void Main(string[] args)
    {
      var p = new List<Person>() {
        new Person {
          Age = 10,
          Name = "Ichiro Suzuki",
          City = "Tokyo"
        },
        new Person {
          Age = 20,
          Name = "Hanako Yamada",
          City = "Sapporo"
        },
        new Person {
          Age = 35,
          Name = "Taro Yamada",
          City = "Yokohama"
        }
      };

      var s = from a in p
          where a.Age < 30
          select new
          {
            a.Name,
            a.City
          };

      foreach (var e in s)
      {
        Console.WriteLine("{0} [{1}]", e.Name, e.City);
      }
    }
  }
}

結果の型を上記のように匿名型によって、その場で定義しています。(select new の部分です。)

また匿名型は名前が無いので、それを受ける変数としては var を用います。

つまり、LINQ に対応するためには、暗黙的な型指定ローカル変数の宣言である var と、 匿名型が必要になるのです。

スポンサーリンク
ホーム > C# の基礎 > 匿名型