いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

C#4.0の追加機能-03(dynamic-03, 動的プログラミング, 制限, 拡張メソッド、ラムダメソッド)


dynamicの続きです。


便利なdynamicキーワードですが、現状、以下の事が出来ません。

  • 拡張メソッドの呼び出し
  • ラムダメソッドの利用


これはつまり以下のコードはエラーとなるという事です。

public static class IntegerExtensions {
    public static int Square(this int self) {
        ...
    }
}

int i = 100;

// 普通に利用.
Console.WriteLine(i.Square());

// dynamic経由で利用
// (実行時にエラーとなる。)
dynamic dynObj = i;
Console.WriteLine(dynObj.Square());
void DoAction(integer i, Action<int> action) {
    action(i);
}

int i = 100;

// 普通に利用
DoAction(i, element => Console.WriteLine(element));

// dynamic経由で利用
// (コンパイル時にエラーとなる)
dynamic dynObj = i;
DoAction(dynObj, element => Console.WriteLine(element));


拡張メソッドの呼び出しは実行時にエラーとなり、ラムダの呼び出しは
コンパイル時にエラーとなります。


つまり、Linqの場合はほぼ全滅になります。


以下、サンプルです。

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

namespace DynamicLookup03 {

    class Program {

        static void Main(string[] args) {
            (new Program()).Execute();

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }

        private void Execute() {
            //
            // dynamicでは、拡張メソッドとラムダメソッドが
            // 利用できない事を試す。
            //
            Console.WriteLine(100.Square());
            100.Times(Console.WriteLine);

            // 拡張メソッドの呼び出し
            // (実行時にエラーとなる)
            //dynamic dynObj = 100;
            //Console.WriteLine(dynObj.Square());

            // ラムダの利用.
            //dynamic dynObj2 = this;
            //dynObj2.ProcessExecute(dynObj2, element => Console.WriteLine(element));
        }

        private void ProcessExecute(int i, Action<int> action) {
            i.Times(action);
        }
    }

    static class IntegerExtensions {

        public static int Square(this int self) {
            return (self * self);
        }

        public static void Times(this int self, Action<int> action) {
            for(int i = 0; i < self; i++) {
                action(i);
            }
        }
    }
}