連載:C# 4入門

第8回 ExpandoObjectを継承した動的拡張できるクラス

株式会社ピーデー 川俣 晶
2011/02/10
Page1 Page2 Page3

メソッド・モドキの追加

 ExpandoObjectはメソッドやプロパティを動的に追加することはできない。しかし、メソッドに関してはそれっぽいことができる。デリゲート型の値を追加することで、呼び出すことができるわけである。

using System;
using System.Dynamic;

class Program
{
  static void Main(string[] args)
  {
    dynamic x = new ExpandoObject();

    x.DoIt = (Action)(() => Console.WriteLine("I'm first!"));
    x.DoIt();

    x.DoIt = (Action)(() => Console.WriteLine("I'm second!"));
    x.DoIt();
  }
}
リスト7

I'm first!
I'm second!
リスト7の実行結果

 ラムダ式はそれだけでは型が決まらないため、「(Action)」というキャストが要求されているが、それ以外は別に難しいこともないだろう。デリゲート型の値を差し替えることで、実行される内容も動的に差し替えが可能になっている。

 引数がある場合もAction型やFunc型を利用すれば問題はない。

using System;
using System.Dynamic;

class Program
{
  static void Main(string[] args)
  {
    dynamic x = new ExpandoObject();
    x.DoIt = (Func<string,string>)
                    ((s) => string.Format("{0} first!",s));
    Console.WriteLine(x.DoIt("I'm"));
  }
}
リスト8

I'm first!
リスト8の実行結果

 これだけである。簡単な割に使い出があるといえる。しかし、乱用はあまりお勧めではない。動的な機能はエラー・チェックが実行時になり、どうしても問題の発覚が遅れがちだからである。

まとめ

 今回のまとめ。

  • 単に実行時に決まるメンバに値を格納するだけなら、ダイナミック・オブジェクトよりExpandoObjectの方がずっと簡単に書ける
  • ダイナミック・オブジェクトと違って、ExpandoObjectを利用する場合は継承して処理方法を記述する必要がない
  • 名前と値に関するさまざまな処理は、ExpandoObjectに実装されたインターフェイスで処理できる
  • しかし、多くの場合、インターフェイスにキャストしないと呼び出せない
  • メンバの名前と値のペアはLINQでクエリすることもできる

 さて、このExpandoObjectも、やはり出番が多いかといえば微妙だ。メンバを実行時に自由に追加できるということは、コンパイル時にはメンバが確定しないということであり、当然IntelliSenseの候補にも動的なメンバは出てこない。

 「A」や「B」あるいが「DoIt」ぐらいならまだしも、長い名前を付けると自分ですべて打たねばならない。「IsAlradyJoinedWithUltraSuperDeluxeMan」というような長い名前を付けてしまうと使い勝手は極端に落ちていく。

 通常は可読性優先で長い名前を付けるのもよいが(それでもC#の機能をフル活用するとコードをかなり短くできる)、動的に扱う場合はIntelliSenseで入力できないので、スペルミスが混入する確率は跳ね上がる。

 やはり、この機能も「中間言語としてのC#」で生きてくるのではないかと思う。一部の動的な言語は、ExpandoObjectと相性がよさそうである。そういう言語からC#への変換プログラムはかなり書きやすくなったのだろうと思う。

 しかし、リフレクションを多用する動的なプログラミングをしていれば、その助けになるという可能性もあるだろう。いずれにしても、そのあたりにいくらでもある普通のプログラムで使って生きる機能ではなさそうである。使うことよりも、使い所を見つけることで評価されそうな機能かもしれない。End of Article

 

 INDEX
  C# 4入門
  第8回 ExpandoObjectを継承した動的拡張できるクラス
    1.このコードは是か非か?
    2.値の列挙/値のチェック/LINQでクエリする/メンバの削除
  3.メソッド・モドキの追加/まとめ
 
インデックス・ページヘ  「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 記事ランキング

本日 月間