[C#] 33. 匿名形式(Anonymous Types)を使い方


Study / C#    作成日付 : 2019/07/20 02:22:03   修正日付 : 2021/09/20 20:38:42

こんにちは。明月です。


この投稿は匿名形式(Anonymous Types)を使い方に関する説明です。


クラスはC#でプログラムを作成するところで最小単位です。

クラスの基本構造はメンバー変数と関数があり、その以外にプロパティ、デリゲート、イベント、インデクスがあります。

link - [C#] 10. クラスを作成する方法(コンストラクタ、デストラクタ)


そして我々が作成したクラスをメモリにインスタンス生成するためにnewというキーワードを使って生成することになります。

using System;

namespace Example
{
  // 例クラス
  class Node
  {
    // メンバー変数プロパティ
    public int Data
    {
      get; set;
    }
    // 出力関数
    public void Print()
    {
      // コンソール出力
      Console.WriteLine(Data);
    }
  }

  class Program
  {
    // 実行関数
    static void Main(string[] args)
    {
      // インスタンス生成
      var node = new Node();
      // インスタンスメンバー変数に値を格納
      node.Data = 100;
      // 出力関数呼び出す。
      node.Print();
      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


クラスで一番重要なことはメンバー変数です。

プロパティはメンバー変数に値を格納するための関数だし、デリゲートやイベント、インデクサーなども関数の役割について区分するための関数です。

関数というのはプログラムを実装するための実行処理だけで、クラスのデータを格納するしクラスのサイズを決定するのは結局メンバー変数です。


でも、その使い目的によりクラスをすべて作成することにはソースがすごく複雑になる可能性もあります。

簡単の例として、単一目的によりデータを渡すためのクラスならそれをためクラスを作成することは無駄なこともあります。改めて説明すると、データを関数のパラメータにより渡す時、原始データだけでパラメータを作成するとパラメータが多くなりますが、パラメータのクラスを作成して渡すとソースが簡単になります。

using System;

namespace Example
{
  // Print関数のパラメータ用のクラス
  class Parameter
  {
    // プロパティ
    public string Header { get; set; }
    // プロパティ
    public string Commnet { get; set; }
    // プロパティ
    public int Data { get; set; }
    // プロパティ
    public String Footer { get; set; }
  }
  class Program
  {
    // 出力関数、ただ原始データでパラメータを受け取る。
    static void Print(string header, string comment, int data, string footer)
    {
      // コンソール出力
      Console.WriteLine(header);
      Console.WriteLine(comment + " = " + data);
      Console.WriteLine(footer);
    }
    // 出力関数、クラスでパラメータを受け取る。
    static void Print(Parameter param)
    {
      // コンソール出力
      Console.WriteLine(param.Header);
      Console.WriteLine(param.Commnet + " = " + param.Data);
      Console.WriteLine(param.Footer);
    }
    // 実行関数
    static void Main(string[] args)
    {
      // 出力関数を呼び出す。
      Print("Test1", "data", 10, "End");
      // 改行
      Console.WriteLine();
      // 出力関数呼び出す。
      Print(new Parameter()
      {
        Header = "Test2",
        Commnet = "data",
        Data = 100,
        Footer = "End"
      });
      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


上の例をみれば、始めの関数の場合はパラメータをただ原始データタイプで受け取ります。簡単な例なのでパラメータが4個ですが、仕様によりこのパラメータが10個、20個になる可能性もあります。

実際にそのように作成するとパラメータが多すぎて可読性が悪くなります。

なので、普通はパラメータのデータのクラスを作成して、クラスからパラメータのデータを受け取りますが、利点はソースが読みやすくなります。


でも、この問題は大きいプロジェクトだと思えば各関数のためパラメータのクラスを作成することはソースコードがすごく多くなります。

それでこのように一回性のインスタンスのための匿名形式のクラスがあります。

using System;

namespace Example
{
  class Program
  {
    // パラメータはvarタイプで受け取られないので、dynamicタイプで受け取る。
    static void Print(dynamic param)
    {
      // コンソール出力
      Console.WriteLine(param.Header);
      Console.WriteLine(param.Commnet + " = " + param.Data);
      Console.WriteLine(param.Footer);
    }
    // 実行関数
    static void Main(string[] args)
    {
      // newキーワードを使ってインスタンスを生成するが、クラス名はない。
      var data = new
      {
        Header = "Test",
        Commnet = "data",
        Data = 100,
        Footer = "End"
      };
      // 出力関数を呼び出す
      Print(data);
      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


上の例でPrint関数のパラメータによりデータインスタンスを渡すために、newキーワードを使ってインスタンスを生成しましたが、クラス名はありません。

インスタンスの変数タイプはvarタイプで設定して、Print関数からはvarタイプの変数名を使えないので、dynamicキーワードでパラメータを受け取りました。


以前のvarタイプとdynamicタイプに関して説明したことがあるので、参考してください。

link - [C#] 27. varキーワードとdynamicキーワード


特にこの匿名形式(Anonymous Types)のクラスタイプはLinq式でよく使います。

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

namespace Example
{
  class Program
  {
    // 実行関数
    static void Main(string[] args)
    {
      // リスト生成
      var list = new List<int>();
      // iが0から9まで
      for (int i = 0; i < 10; i++)
      {
        // リストにデータを格納
        list.Add(i);
      }
      // 6以上の値を匿名形式のListタイプでリターンする。
      // 繰り返し、抽出
      foreach (var node in list.Where(x => x > 5).Select(x => new { Data = x }))
      {
        // コンソール出力
        Console.WriteLine(node.Data);
      }

      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


ここまで匿名形式(Anonymous Types)を使い方に関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

#C#
最新投稿