連載:C# 4入門

第1回 dynamic型

株式会社ピーデー 川俣 晶
2010/07/16
Page1 Page2 Page3

dynamic型と匿名型

 匿名型は、名前もなく、定義も存在しない型のオブジェクトを作るための機能である。厳密にいえば、型は存在するのだが、C#のソース・コードでアクセスできる形態では存在しないのである。しかし、それが有効利用できる範囲はあまり広くはなかった。1つのメソッドの外に持ち出すことは不可能ではないが、持ち出してしまうと、利用にはリフレクションが必要だったからである。

 しかし、dynamic型が一挙に問題を解決してくれた。dynamic型として返せば、簡単に内容にアクセスできるのである。

using System;

class Program
{
  private static dynamic GetObject()
  {
    return new { YourName = "Arashi隊員", YourScore = 1000 };
  }

  static void Main(string[] args)
  {
    dynamic a = GetObject();
    Console.WriteLine("{0}のスコアは{1}点です。",
                            a.YourName, a.YourScore);
  }
}
リスト6 dynamic型と匿名型を使ったオブジェクトの受け渡し

Arashi隊員のスコアは1000点です。
リスト6の実行結果

 もちろん、C#としての定義がない型なので、名前を書き間違えてもコンパイル時にエラーは出ず、実行時に例外が発生することになる。

dynamic型と動的言語

 dynamic型を使うとソース・コードがスマートになる事例はほかにもある。

 例えば、.NET Framework上でPython言語を使用可能にする「IronPython」というソフトウェアが存在するが、これを用いるとC#からPythonで書かれたコードを簡単に利用できる。

 以下、実際にPythonで記述されたメソッドを呼び出した事例を見てみよう。なお、Visual Studio 2010とIronPython 2.6.1を使用している。

 また、前準備としては以下の手順を必要とする。

  • IronPythonに含まれているアセンブリのIronPython.dll、Microsoft.Dynamic.dll、Microsoft.Scripting.dllへの参照を追加しておく
  • テキスト・ファイルをプロジェクトに追加して、sample.pyというファイル名を付けておく

 ここで以下の2つのファイルを書き込む。

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

class Program
{
  static void Main(string[] args)
  {
    ScriptRuntime py = Python.CreateRuntime();
    dynamic sample = py.UseFile(@"sample.py);
    dynamic r = sample.getWeapon();

    Console.WriteLine("{0} has a {1}.", r.name, r.weapon);
  }
}
リスト7 Program.cs

class WeaponInfo:
  name=0
  weapon=0

def getWeapon():
  a = WeaponInfo()
  a.name = "Cyber Ryo"
  a.weapon = "Colt Python"
  return a
リスト8 sample.py

Cyber Ryo has a Colt Python.
リスト8の実行結果

 さて、このプログラムは、2つのメンバ(nameとweapon)を持つオブジェクトを結果として受け取っている。ここで問題となるのは、受け取ったオブジェクトの定義がどこにあるのかである。

 もちろん、sample.pyにあるWeaponInfoクラスの定義がそれに当たるのだが、C#コンパイラがコンパイル時に参照できるのはC#の定義か、あるいは.NET Frameworkで作成されたアセンブリである。つまり、Pythonのソース・コードは参照できないので、このクラスの定義はコンパイル時に参照できない。

 しかし、dynamic型を用いることで、このソース・コードは大幅に簡素化されている。コンパイラは参照できない定義でも、ランタイムは実行中にそのようなメンバが存在していることを動的に認識し、dynamic型を経由すればそのメンバの値も使用できるのである。

まとめ

 今回の内容をまとめておく。

  • dynamic型は実行時に型を解釈する
  • コンパイル時に定義を知らないオブジェクトが持つ情報にアクセスできる
  • 名前さえ一致していれば、どのクラスの定義でも、定義がなくてもアクセスできる
  • 匿名型の使い勝手が向上する
  • 動的言語との相互運用に便利
  • つづりの間違いは実行するまでエラーにならない
  • 定義不要で扱えるためソースは短くなるが、性能面では静的な定義に劣る

 dynamic型は必ずしも不可能を可能にした型というわけではない。それ以前でも、リフレクションで同じような機能を記述することはできたが、dynamic型はそのためのハードルを大きく下げてくれたのである。

 実行効率が悪いことを気にするのであれば、対策はある。並列実行である。増え続けるコアを同時に活用すれば性能低下は最小限に食い止められる。次回からはそのための機能を見ていこう。End of Article

 

 INDEX
  C# 4入門
  第1回 dynamic型
    1.C# 4がやってきた
    2.dynamic型/ダック・タイピング
  3.dynamic型と匿名型/dynamic型と動的言語/まとめ
 
インデックス・ページヘ  「C# 4入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間