Кроме обычных методов структура может содержать специальный метод - конструктор, который выполняет некую начальную инициализацию объекта, например, присваивает всем полям некоторые значения по умолчанию. В принципе для структуры необязательно использовать конструктор:
1 | Book book1; |
Однако в этом случае, чтобы использовать структуру, нам надо будет первоначально проинициализировать все ее поля:
1 2 3 | book1.name = "Война и мир"; book1.author = "Л. Н. Толстой"; book1.year = 1869; |
Вызов же конструктора по умолчанию позволяет автоматически проинициализировать поля структуры значениями по умолчанию (например, для числовых данных - это число 0):
1 | Book book2=new Book(); // использование конструктора |
Вызов конструктора имеет следующий синтаксис: new название_структуры ([список_параметров]). Теперь попробуем определить свой конструктор:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | struct Book { public string name; public string author; public int year; // конструкор public Book(string n, string a, int y) { name = n; author = a; year = y; } public void Info() { Console.WriteLine("Книга '{0}' (автор {1}) была издана в {2} году", name, author, year); } } |
Конструктор по сути является обычным методом, только не имеет возвращаемого значения, и его название всегда совпадает с именем структуры или класса. Теперь используем его:
|
|
1 2 | Book book=new Book("Война и мир", "Л. Н. Толстой", 1869); book.Info(); |
Теперь нам не надо вручную присваивать значения полям структуры - их инициализацию выполнил конструктор.
Лекция 18. Кортежи
Кортежи предоставляют удобный способ для работы с набором значений, который был добавлен в версии C# 7.0.
Кортеж представляет набор значений, заключенных в круглые скобки:
var tuple = (5, 10);
В данном случае определен кортеж tuple, который имеет два значения: 5 и 10. В дальнейшем мы можем обращаться к каждому из этих значений через поля с названиями Item[порядковый_номер_поля_в_кортеже]. Например:
static void Main(string[] args)
{
var tuple = (5, 10);
Console.WriteLine(tuple.Item1); // 5
Console.WriteLine(tuple.Item2); // 10
tuple.Item1 += 26;
Console.WriteLine(tuple.Item1); // 31
Console.Read();
}
В данном случае тип определяется неявно. Но мы ткже можем явным образом указать для переменной кортежа тип:
(int, int) tuple = (5, 10);
Так как кортеж содержит два числа, то в определении типа нам надо указать два числовых типа. Или другой пример определения кортежа:
(string, int, double) person = ("Tom", 25, 81.23);
Первый элемент кортежа в данном случае представляет строку, второй элемент - тип int, а третий - тип double.
Мы также можем дать названия полям кортежа:
var tuple = (count:5, sum:10);
Console.WriteLine(tuple.count); // 5
Console.WriteLine(tuple.sum); // 10
Теперь чтобы обратиться к полям кортежа используются их имена, а не названия Item1 и Item2.
Мы даже можем не использовать переменную для определения всего кортежа, а использовать отдельные переменные для его полей:
|
|
static void Main(string[] args)
{
var (name, age) = ("Tom", 23);
Console.WriteLine(name); // Tom
Console.WriteLine(age); // 23
Console.Read();
}
В этом случае с полями кортежа мы сможем работать как с переменными, которые определены в рамках метода.
Использование кортежей
Кортежи могут передаваться в качестве параметров в метод, могут быть возвращаемым результатом функции, либо использоваться иным образом.
Например, одной из распространенных ситуаций является возвращение из функции двух и более значений, в то время как функция можно возвращать только одно значение. И кортежи представляют оптимальный способ для решения этой задачи:
static void Main(string[] args)
{
var tuple = GetValues();
Console.WriteLine(tuple.Item1); // 1
Console.WriteLine(tuple.Item2); // 3
Console.Read();
}
private static (int, int) GetValues()
{
var result = (1, 3);
return result;
}
Здесь определен метод GetValues(), который возвращает кортеж. Кортеж определяется как набор значений, помещенных в круглые скобки. И в данном случае мы возвращаем кортеж из двух элементов типа int, то есть два числа.
Другой пример:
static void Main(string[] args)
{
var tuple = GetNamedValues(new int[]{ 1,2,3,4,5,6,7});
Console.WriteLine(tuple.count);
Console.WriteLine(tuple.sum);
Console.Read();
}
private static (int count, int sum) GetNamedValues(int[] numbers)
{
var result = (sum:0, count: 0);
for (int i=0; i < numbers.Length; i++)
{
result.sum += numbers[i];
result.count++;
}
return result;
}
И также кортеж может передаваться в качестве параметра в метод:
static void Main(string[] args)
{
var (name, age) = GetTuple(("Tom", 23), 12);
Console.WriteLine(name); // Tom
Console.WriteLine(age); // 35
Console.Read();
}
private static (string name, int age) GetTuple((string n, int a) tuple, int x)
{
var result = (name: tuple.n, age: tuple.a + x);
return result;
}