2012-05-09 68 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派生出來,如果你想讓你的對象像那樣行爲,你有兩個解決方案,即imo: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 
} 

現在我可以這樣做:和speak(new Goose());,它會編譯和運行如果兩個DuckGoose有方法Quack(),如果他們不這樣做,它會引發一個例外。 (同你)

當你調用一個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

如果您不想將您的課程用作「詞典」,例如如果它代表一個xml或csv文件,您可以在其中動態訪問列和元素,如'file.nameOfSecondColumn [row]' – phg

+0

@RoyiNamir我更新了我的答案。 – gideon