Добавление неизвестных (во время разработки) свойств в ExpandoObject
просто исследуя С# 4. Попытка разобраться во всех этих динамических материалах. Извините, если этот вопрос глупый, нет опыта в этом домене.
Если у меня есть ExpandoObject и вы хотите добавить общедоступные свойства (с get и set) к нему во время выполнения, как бы я это сделал?
Например, у меня есть documentTemplate и документ, который имеет свойство, указывающее на documentTemplate. Этот документTemplate имеет несколько названий тегов (например, возможности, разработанные среди студентов), которые следует решать при создании документа (например, Концентрация, память и т.д.). Поэтому, как только шаблон установлен в документе, я хочу создать класс, который имеет свойства с теми же именами, что и названия тегов в шаблоне, а затем с помощью некоторого элемента пользовательского интерфейса, такого как PropertyGrid, я могу иметь пользователя введите значения тегов в заголовки тегов.
Спасибо за чтение!
Ответы
Ответ 1
Я задавался вопросом, как можно было бы добавить участников в класс "на лету" и придумал этот пример:
using System;
using System.Collections.Generic;
using System.Dynamic;
class Program
{
static void Main()
{
dynamic expando = new ExpandoObject();
var p = expando as IDictionary<String, object>;
p["A"] = "New val 1";
p["B"] = "New val 2";
Console.WriteLine(expando.A);
Console.WriteLine(expando.B);
}
}
Точка этого фрагмента кода состоит в том, что члены A и B определены как строковые литералы (жестко закодированные/строковые) и добавлены через интерфейс ExpandoObject IDictionary. Мы проверяем существование и значения ключей (и доказываем концепцию), обращаясь к ним напрямую и выводя на консоль.
Ответ 2
Можно добавить свойства делегата в ExpandoObject
, которые затем действуют (почти) точно так же, как методы. например.
dynamic obj = new ExpandoObject();
obj.GetDocumentTemplate = () => { ... };
...
obj.GetDocumentTemplate(); // invokes delegate
Ответ 3
Да, ExpandoObject очень удобен для динамического добавления свойств в "пакет свойств". Однако представление о предоставлении такого свойства геттер и сеттер не поддерживается. Возможно, это ясно, если вы подумаете об этом немного: это не будет динамическим свойством, если вы уже знаете, что должны делать геттер и сеттер. Самое близкое, что вы можете получить, - это реализовать событие INotifyPropertyChanged, чтобы вы могли обнаружить изменения. Пример кода:
using System;
using System.Dynamic;
using System.ComponentModel;
class Program {
static void Main(string[] args) {
dynamic obj = new ExpandoObject();
obj.test = 42; // Add a property
Console.WriteLine(obj.test);
var inpc = (INotifyPropertyChanged)obj;
inpc.PropertyChanged += inpc_PropertyChanged;
obj.test = "foo";
Console.ReadLine();
}
static void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e) {
Console.WriteLine("'{0}' property changed", e.PropertyName);
}
}
Ответ 4
Ответы до сих пор хорошо освещают основы, но я чувствовал, что статья MSDN Magazine также стоит того, чтобы поделиться:
http://msdn.microsoft.com/en-us/magazine/ff796227.aspx
Он описывает некоторые примеры использования динамического ввода XML для динамического создания и использования ExpandoObjects.
Ответ 5
Я только что обнаружил этот интересный факт: Привязки XAML к ExpandoObject также создадут свойства, к которым пытается привязать привязка.
Мне все еще нужно больше творчества, чтобы узнать, для чего это может быть полезно. Создание динамического объекта в пользовательском интерфейсе? звучит круто: D Я попробую что-нибудь.