2012-05-09 3 views
8

Im пытается добавить функцию во время выполнения, что-то вроде этого:с помощью динамического добавления методов?

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» не содержит определение для

Isnt динамика «шарлатан» должен позволить мне сделать это?

действительно ли новый ExpandoObject является единственным решением?

У меня есть утка класс уже. как я могу сделать это Expando? - Могу ли я сделать утину, как expando?

+0

Для некоторых совершенно непонятных причин мое сообщение было удалено. Кстати, вы не можете извлечь из ExpandoObject, и если вы хотите, чтобы ваш объект вел себя так, у вас есть 2 решения, imo: 1. Создайте Expando и сначала добавьте все свойства и методы, которые у вас есть в Duck, и не делайте используйте 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());, он будет компилировать и запускать, если оба Duck и Goose есть метод Quack(), если они этого не делают, это вызывает исключение. (Тот же самый, который вы получаете)

Когда вы вызываете метод/свойство по типу dynamic, он разрешает только во время выполнения и не выполняет проверку компилятора.

The 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 [строка]' – phg

+0

@RoyiNamir Я обновил свой ответ. – gideon