271
Свойства.без.параметров
рис. 10.1.
.Настройки.отладчика.Visual.Studio
инициализаторы объектов и коллекций
Создание объекта с заданием некоторых открытых свойств (или полей) — чрезвы-
чайно распространенная операция. Для ее упрощения в C# предусмотрен специ-
альный синтаксис инициализации объекта, например:
Employee e = new Employee() { Name = "Jeff", Age = 45 };
В этом выражении я создаю объект
Employee
, вызывая его конструктор без па-
раметров, и затем назначаю открытому свойству
Name
значение
Jeff
, а открытому
свойству
Age
— значение 45. Этот код идентичен следующему коду (в этом нетрудно
убедиться, просмотрев IL-код обоих фрагментов):
Employee e = new Employee();
e.Name = "Jeff";
e.Age = 45;
Реальная выгода от синтаксиса инициализатора объекта состоит в том, что
он позволяет программировать в контексте выражения, строя функции, которые
улучшают читабельность кода. Например, можно написать:
String s = new Employee() { Name = "Jeff", Age = 45 }.ToString().ToUpper();
В одном выражении я сконструировал объект
Employee
, вызвал его конструктор,
инициализировал два открытых свойства, вызвал метод
ToString
, а затем метод
272
Глава.10 .Свойства
ToUpper
. С# также позволяет опустить круглые скобки перед открывающей фигур-
ной скобкой, если вы хотите вызвать конструктор без параметров. Для следующего
фрагмента генерируется программный код, идентичный предыдущему:
String s = new Employee { Name = "Jeff", Age = 45 }.ToString().ToUpper();
Если тип свойства реализует интерфейс
IEnumerable
или
IEnumerable
,
то свойство является коллекцией, а инициализация коллекции является до-
полняющей операцией (а не заменяющей). Например, пусть имеется следующее
определение класса:
public sealed class Classroom {
private List m_students = new List();
public List Students { get { return m_students; } }
public Classroom() {}
}
Следующий код создает объект
Classroom
и инициализирует коллекцию
Stu-
dents
:
public static void M() {
Classroom classroom = new Classroom {
Students = { "Jeff", "Kristin", "Aidan", "Grant" }
};
// Вывести имена 4 студентов, находящихся в классе
foreach (var student in classroom.Students)
Console.WriteLine(student);
}
Во время компиляции этого кода компилятор увидит, что свойство
Students
имеет тип
List
и что этот тип реализует интерфейс
IEnumerable
.
Компилятор предполагает, что тип
List
предоставляет метод с именем
Add
(потому что большинство классов коллекций предоставляет метод
Add
для
добавления элементов в коллекцию). Затем компилятор сгенерирует код для вы-
зова метода
Add
коллекции. В результате представленный код будет преобразован
компилятором в следующий:
public static void M() {
Classroom classroom = new Classroom();
classroom.Students.Add("Jeff");
classroom.Students.Add("Kristin");
classroom.Students.Add("Aidan");
classroom.Students.Add("Grant");
// Вывести имена 4 студентов, находящихся в классе
foreach (var student in classroom.Students)
Console.WriteLine(student);
}
273
Свойства.без.параметров
Если тип свойства реализует интерфейс
IEnumerable
или
IEnumerable
, но
не предлагает метод
Add
, тогда компилятор не разрешит использовать синтаксис
инициализации коллекции для добавления элемента в коллекцию, вместо этого
компилятор выведет такое сообщение (ошибка CS0117:
System.Collections.
Generic.IEnumerable
не содержит определения для
Add
):
error CS0117: 'System.Collections.Generic.IEnumerable' does not
contain a definition for 'Add'
Некоторые методы
Add
принимают различные аргументы. Например, вот метод
Add
класса
Dictionary
:
public void Add(TKey key, TValue value);
При инициализации коллекции методу
Add
можно передать несколько аргумен-
тов, для чего используется синтаксис с фигурными скобками:
var table = new Dictionary {
{ "Jeffrey", 1 }, { "Kristin", 2 }, { "Aidan", 3 }, { "Grant", 4 }
};
Это равносильно следующему коду:
var table = new Dictionary();
table.Add("Jeffrey", 1);
table.Add("Kristin", 2);
table.Add("Aidan", 3);
table.Add("Grant", 4);
Do'stlaringiz bilan baham: |