プログラム言語 データ型:Dynamic型
概要
コンパイル時に型の整合性をチェックせずに、実行時に整合性をチェックする手法。
ポリモーフィズムの様な実装が可能。
動的な型設定
class MyClass
{
public readonly string MyName = "山田太郎";
public static object GetObjectMyClass()
{
return new MyClass();
}
}
static void Main(string[] args)
{
NG
var m = MyClass.GetObjectMyClass();
var name = m.MyName;
→ コンパイルエラー
※実行時にインスタンスを取得するので、
コンパイル時にはインスタンス変数にアクセスできない。
OK
object m = MyClass.GetObjectMyClass();
var name = a.GetType().GetField("MyName").GetValue(m);
※動的にインスタンス情報を取得
OK
var m = new MyClass();
var name = m.MyName;
(参考)
var age = m.MyAge;
→ コンパイルエラー
※そんなプロパティは無い
OK
dynamic m = MyClass.GetObjectMyClass();
var name = m.MyName;
→ コンパイル:OK / 実行:OK
※Dynamic型は事前バインディングを行わないので、コンパイルエラーは発生しない。
(参考)
var age = m.Age;
→ コンパイル:OK / 実行時エラー
※そんなプロパティは無い。
}
ダックタイピング
動的な型の設定方法
「アヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである。」
アヒルでない別の動物がアヒルの様に行動していてもアヒルと見なす
という考え方。
メソッド名が同じなら継承関係の無い別クラスでも実行を認める等。
class 醜いアヒルの子
{
public void 鳴く()
{
Console.WriteLine("くわっ! by 醜いアヒルの子");
}
}
class 白鳥
{
public void 鳴く()
{
Console.WriteLine("くわっ! by 白鳥");
}
}
class Program
{
private static void 鳴け(dynamic 鳥)
{
鳥.鳴く();
}
static void Main(string[] args)
{
鳴け((dynamic)new 醜いアヒルの子());
鳴け((dynamic)new 白鳥());
}
}
→
くわっ! by 醜いアヒルの子
くわっ! by 白鳥
各クラスが継承関係にある場合にこの処理を通すテクニック:ポリモーフィズムと違い、
Dynamic型の場合は、メンバー名が同じであれば実行できてしまう。
コンパイル時のチェックが無い為に信頼性は低下する。
また、実行速度も低下する。
匿名型(匿名クラス)の利用
private static dynamic GetObject()
{
return new { Name = "システム開発者", Age = 37 };
}
static void Main(string[] args)
{
var newObject = GetObject();
Console.WriteLine(newObject.Name + "(" + newObject.Age + ")");
}