TOC

This article has been localized into Russian by the community.

Введение:

Объект ExpandoObject

Как мы видели в предыдущей статье, мы можем использовать ключевое слово dynamic для хранения объекта, в котором мы определяем свойства, без необходимости сначала определять класс. То, что мы не можем сделать с динамическим объектом, - это динамическое добавление свойств к нему после инициализации объекта. Если вам нужна эта конкретная способность, C# поставляется с решением для вас: ExpandoObject. Давайте перейдем прямо к примеру, чтобы вы могли увидеть, как легко это использовать:

dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
user.HomeTown = "New York";
Console.WriteLine(user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown);

Вы заметите, что я объявляю объект с динамическим типом, даже если я создаю экземпляр ExpandoObject. Причина в том, что если объект был объявлен как ExpandoObject, компилятор проверит его и сразу же пожалуется на отсутствие свойств, которые мы для него придумываем (имя, возраст и так далее). Мы можем предотвратить это, объявив его динамическим, что, как мы узнали в предыдущей статье, помешает компилятору проверять наличие используемых свойств.

Классная вещь заключается в том, что ExpandoObject, конечно, может иметь свойства, которые также ExpandoObject, позволяя сделать сложные типы на лету, как в этом примере:

dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;

user.HomeTown = new System.Dynamic.ExpandoObject();
user.HomeTown.Name = "New York";
user.HomeTown.ZipCode = 10001;

Console.WriteLine(user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown.Name + " [" + user.HomeTown.ZipCode + "]");

Я просто изменяю свойство HomeTown со строки на ExpandoObject, а затем добавляю в него свойства, в данном случае имя и почтовый индекс города. Но на этом все не должно заканчиваться - мы можем даже добавить методы к объекту, опять же на лету, используя некоторые довольно сложные трюки:

user.DescribeUser = (Func<String>)(() => {
return user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown.Name + " [" + user.HomeTown.ZipCode + "]";
});

Console.WriteLine(user.DescribeUser());

Довольно аккуратный материал, но что такое ExpandoObject на самом деле? Он реализует несколько интересных интерфейсов, но один из них - IDictionary<string, object> - это означает, что под всем синтаксическим сахаром Ваш ExpandoObject-это просто словарь, который содержит значения объектов на основе строковых ключей. Это также означает, что итерация по ExpandoObject так же проста, как итерация по обычному словарю. Это очень практично:

dynamic user = new System.Dynamic.ExpandoObject();  
user.Name = "John Doe";  
user.Age = 42;  

foreach (KeyValuePair<string, object> kvp in user)
{
    Console.WriteLine(kvp.Key + ": " + kvp.Value);
}

Резюме

Тип ExpandoObject позволяет Вам определять объекты на лету и затем добавлять свойства к нему всякий раз, когда вы хотите. Так как это в основном динамический тип, он наследует те же преимущества и недостатки, что мы обсуждали в предыдущей статье. В качестве бонуса, однако, ExpandoObject реализует интерфейс INotifyPropertyChanged, который вы, безусловно, оцените, если вы используете, например, WPF для вашего приложения.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!