2012-05-09 20 views
8

Im próbuje dodać funkcję wykonywania, coś takiego:za pomocą Dynamic, aby dodać metody?

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' nie zawierają definicji dla 'szarlatan'

isnt dynamiki powinien pozwolić mi to zrobić?

Czy nowy ExpandoObject jest jedynym rozwiązaniem?

Mam już klasę kaczki już. jak mogę zrobić to Expando? - Czy mogę sprawić, żeby kaczka zachowywała się jak expando?

+0

Dla niektórych całkowicie niejasnych powodów mój post został usunięty. Przy okazji, nie możesz czerpać z ExpandoObject, a jeśli chcesz, aby twój obiekt zachowywał się tak jak ten, masz 2 rozwiązania, imo: 1. Utwórz Expando i dodaj początkowo wszystkie właściwości i metody, które masz w Kaczce, i nie użyj Duck. 2. Wygeneruj własny ExpandoObject. Zobacz tutaj: [Dynamiczne zachowanie obiektów w środowisku wykonawczym z niestandardowym ExpandoObject] (http://www.codeproject.com/Articles/91889/Dynamic-Behaviour-on-Objects-at-Runtime-With-Custo), aby uzyskać bardziej szczegółowy przykład i wyprowadzić z niego kaczkę. – Tigran

Odpowiedz

14

Nie można dodawać właściwości dowolnego typu (nawet funkcji) do istniejącego typu .

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

Można użyć ExpandoObject choć:

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

nie mylić z tym, co dynamiczne typ robi.

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

Teraz mogę zrobić: i speak(new Goose());, będzie to skompilować i uruchomić, jeśli zarówno Duck i Goose mieć metodę Quack(), jeśli nie, to podnosi wyjątek. (Ten sam, który otrzymujesz)

Wywołanie metody/właściwości w typie dynamic rozwiązuje tylko to w czasie wykonywania i nie sprawdza kompilatora.

Obiekt ExpandoObject umożliwia tworzenie właściwości w locie.


Aby odpowiedzieć na to pytanie w komentarzu, tak ja to widzę jest, jeśli trzeba własne klasy, które potrzebne zdolności do tworzenia nowych właściwości można dziedziczyć z DynamicObject. Tak (zaadaptowane z 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; 
    } 
} 

Następnie można zrobić:

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

thnaks, ale dlaczego miałbym kiedykolwiek dziedziczyć z System.Dynamic.DynamicObject? jedynym scenariuszem, jaki widzę - jest zastąpienie tryGetXXX itp. metod .... –

+0

Jeśli nie chcesz używać swojej klasy jako "słownika", np. jeśli reprezentuje plik xml lub csv, w którym można dynamicznie uzyskać dostęp do kolumn i elementów, takich jak 'file.nameOfSecondColumn [wiersz]' – phg

+0

@RoyiNamir Zaktualizowałem moją odpowiedź. – gideon

Powiązane problemy