2012-05-09 4 views
8

イム、実行時にそのような何かの機能を追加しようとしている:Dynamicを使用してメソッドを追加しますか?

static void Main() 
{ 
dynamic d = new Duck(); 
d.Quack =(Action) (() => Console.WriteLine("1")); //decalre a new method on runtime ?? 
d.Quack(); 

} 

public class Duck : System.Dynamic.DynamicObject 
{ 
    //... 
} 

「をUserQuery.Duck」「クワック」

イマイチダイナミックは私がそれを行うことができなければならないの定義が含まれていませんか?

は新品ですExpandoObjectは唯一の解決策ですか?

私はダッククラスがすでにです。どうすればそれをExpandoにすることができますか? - 私はexpandoのようなアヒルの行為をすることができますか?

+0

。ところで、ExpandoObjectから派生することはできません。オブジェクトをそのように動作させたい場合は、次の2つのソリューションがあります。1. Expandoを作成し、最初にDuckにあるすべてのプロパティとメソッドを追加します。ダックを使用してください。 2.独自のExpandoObjectを生成します。ここをクリックしてください:[カスタムExpandoObjectを使用して実行時のオブジェクトの動的挙動](http://www.codeproject.com/Articles/91889/Dynamic-Behaviour-on-Objects-at-Runtime-With-Custo)そこからアヒルを引き出す。 – Tigran

答えて

14

既存のタイプのには、どのタイプのプロパティ(関数も含む)を追加することはできません。

dynamic d = new Duck(); 
d.Quack = "Quack";//fails because there is no such property on duck 

あなたはしかしExpandoObjectを使用することができます。

dynamic d = new ExpandoObject(); 
d.Quack = (Action)(() => System.Console.WriteLine("1")); 
d.Quack(); 

は、動的型が何をするかと混同しないでください。

void speak(dynamic d) 
{ 
d.Quack();//this is NOT checked at compile time 
} 

は今、私が行うことができます。 DuckGooseの両方が、彼らがいない場合、それは例外を発生させ、方法 Quack()を持っている場合と speak(new Goose());は、それがコンパイルして実行します。

dynamicタイプのメソッド/プロパティを呼び出すと、実行時に解決され、コンパイラチェックは行われません。

ExpandoObjectでは、オンザフライでプロパティを作成できます。


コメントにあなたの質問に答えるために、あなたがDynamicObjectから継承することができ、新しいプロパティを作成する機能を必要とする独自のクラスを必要とする場合、私はそれを見る方法が、あります。このように(this msdn pageから適応):

class DynamicDuck : DynamicObject 
{ 
     Dictionary<string, object> dictionary 
      = new Dictionary<string, object>(); 
    public int Count 
    { 
     get 
     { 
      return dictionary.Count; 
     } 
    } 
    public override bool TryGetMember(
      GetMemberBinder binder, out object result) 
    { 
      string name = binder.Name.ToLower(); 
      return dictionary.TryGetValue(name, out result); 
    } 
    public override bool TrySetMember(
     SetMemberBinder binder, object value) 
    { 
      dictionary[binder.Name.ToLower()] = value; 
      return true; 
    } 
} 

が次にあなたができる:私のポストが削除されたいくつかの絶対にあいまいな理由から

dynamic d = new DynamicDuck(); 
d.firstname = "Gideon"; 
d.Quack = (Action)(() => System.Console.WriteLine("Quack")); 
+0

thnaksしかし、なぜ私はこれまでSystem.Dynamic.DynamicObjectから継承したいのですか?私が見る唯一のシナリオは、tryGetXXXなどのメソッドをオーバーライドすることです。 –

+0

クラスを「辞書」として使用したくない場合、たとえば、それが 'file.nameOfSecondColumn [row]'のように列や要素に動的にアクセスできるxmlやcsvファイルを表している場合 – phg

+0

@RoyiNamir私の答えを更新しました。 – gideon

関連する問題