Net framework 5, а также среды Visual Studio 2012 и C#



Download 6,27 Mb.
Pdf ko'rish
bet195/658
Sana12.06.2023
Hajmi6,27 Mb.
#950840
1   ...   191   192   193   194   195   196   197   198   ...   658
Bog'liq
CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C

анонимные типы
Механизм анонимных типов в С# позволяет автоматически объявить кортежный 
тип при помощи простого синтаксиса. 
Кортежный тип
(tuple type)
1
— это тип, 
который содержит коллекцию свойств, каким-то образом связанных друг с дру-
гом. В первой строке следующего программного кода я определяю класс с двумя 
свойствами (
Name
типа 
String
и 
Year
типа 
Int32
), создаю экземпляр этого типа 
и назначаю свойству 
Name
значение 
Jeff
, а свойству 
Year
— значение 1964.
// Определение типа, создание сущности и инициализация свойств
var o1 = new { Name = "Jeff", Year = 1964 };
// Вывод свойств на консоль
Console.WriteLine("Name={0}, Year={1}", o1.Name, o1.Year); // Выводит: 
// Name=Jeff, Year=1964
Здесь создается анонимный тип, потому что не был определен тип имени после 
слова 
new
, таким образом, компилятор автоматически создает имя типа, но не со-
1
Термин «tuple» возник как «обобщение» последовательности: single, double, triple, 
quadruple, quintuple, n-tuple.


274
Глава.10 .Свойства
общает какое оно (поэтому тип и назван анонимным). Использование синтаксиса 
инициализации объекта обсуждалось в предыдущем разделе. Итак, я, как разработ-
чик, не имею понятия об имени типа на этапе компиляции и не знаю, с каким типом 
была объявлена переменная 
o1
. Однако проблемы здесь нет — я могу использовать 
механизм неявной типизации локальной переменной, о котором говорится в гла-
ве 9, чтобы компилятор определил тип по выражению в правой части оператора 
присваивания (
=
).
Итак, посмотрим, что же действительно делает компилятор. Обратите внимание 
на следующий код:
var o = new { property1 = expression1, ..., propertyN = expressionN };
Когда вы пишете этот код, компилятор определяет тип каждого выражения, 
создает закрытые поля этих типов, для каждого типа поля создает открытые свой-
ства только для чтения и для всех этих выражений создает конструктор. Код кон-
структора инициализирует закрытые поля только для чтения путем вычисления 
результирующих значений. В дополнение к этому, компилятор переопределяет 
методы 
Equals

GetHashCode
и 
ToString
объекта и генерирует код внутри всех 
этих методов. Класс, создаваемый компилятором, выглядит следующим образом:
[CompilerGenerated]
internal sealed class <>f__AnonymousType0<...>: Object {
private readonly t1 f1;
public t1 p1 { get { return f1; } }
...
private readonly tn fn;
public tn pn { get { return fn; } }
public <>f__AnonymousType0<...>(t1 a1, ..., tn an) {
f1 = a1; ...; fn = an; // Назначает все поля
}
public override Boolean Equals(Object value) {
// Возвращает false, если какие-либо поля не совпадают;
// иначе возвращается true
}
public override Int32 GetHashCode() {
// Возвращает хеш-код, сгенерированный из хеш-кодов полей
}
public override String ToString() {
// Возвращает пары "name = value", разделенные точками
}
}
Компилятор генерирует методы 
Equals
и 
GetHashCode
, чтобы экземпляры ано-
нимного типа моги размещаться в хеш-таблицах. Неизменяемые свойства, в отличие 


275
Свойства.без.параметров
от свойств для чтения и записи, помогают защитить хеш-код объекта от изменений. 
Изменение хеш-кода объекта, используемого в качестве ключа в хеш-таблице, мо-
жет помешать нахождению объекта. Компилятор генерирует метод 
ToString
для 
упрощения отладки. В отладчике Visual Studio можно навести указатель мыши на 
переменную, связанную с экземпляром анонимного типа, и Visual Studio вызовет 
метод 
ToString
и покажет результирующую строку в окне подсказки. Кстати, 
IntelliSense-окно в Visual Studio будет предлагать имена свойств в процессе на-
писания кода в редакторе — очень полезная функция.
Компилятор поддерживает два дополнительных варианта синтаксиса объявле-
ния свойства внутри анонимного типа, где на основании переменных определяются 
имена и типы свойств:
String Name = "Grant";
DateTime dt = DateTime.Now;
// Анонимный тип с двумя свойствами
// 1. Строковому свойству Name назначено значение Grant
// 2. Свойству Year типа Int32 Year назначен год из dt
var o2 = new { Name, dt.Year };
В данном примере компилятор определяет, что первое свойство должно на-
зываться 
Name
. Так как 
Name
— это имя локальной переменной, то компилятор 
устанавливает значение типа свойства аналогичного типу локальной переменной, 
то есть 
String
. Для второго свойства компилятор использует имя поля/свойства: 
Year

Year
— свойство класса 
DateTime
с типом 
Int32
, а следовательно, свойство 
Year
в анонимном типе будет относиться к типу 
Int32
. Когда компилятор создает 
экземпляр анонимного типа, он назначает экземпляру 
Name
свойство с тем же зна-
чением, что и у локальной переменной 
Name
, так что свойство 
Name
будет связано 
со строкой 
Grant
. Компилятор назначит свойству экземпляра 
Year
то же значение, 
что и возвращаемое значение из 
dt
свойства 
Year
.
Компилятор очень разумно выясняет анонимный тип. Если компилятор видит, 
что вы определили множество анонимных типов с идентичными структурами, 
то он создает одно определение для анонимного типа и множество экземпляров 
этого типа. Под одинаковой структурой я подразумеваю, что анонимные типы 
имеют одинаковые тип и имя для каждого свойства и что эти свойства определены 
в одинаковом порядке. В коде из приведенного примера тип переменной 
o1
и тип 
переменной 
o2
одинаков, так как в двух строках кода определен анонимный тип со 
свойством 
Name/String
и 
Year/Int32
, и 
Name
стоит перед 
Year
.
Раз две переменные относятся к одному типу, открывается масса полезных воз-
можностей — например, проверить, содержат ли два объекта одинаковые значения, 
и присвоить ссылку на один объект переменной другого объекта:
// Совпадение типов позволяет осуществлять операции сравнения и присваивания
Console.WriteLine("Objects are equal: " + o1.Equals(o2));
o1 = o2; // Присваивание


276
Глава.10 .Свойства
Раз эти типы идентичны, то можно создать массив явных типов из анонимных 
типов (о массивах см. главу 16):
// Это работает, так как все объекты имею один анонимный тип
var people = new[] {
o1, // См. ранее в этом разделе
new { Name = "Kristin", Year = 1970 },
new { Name = "Aidan", Year = 2003 },
new { Name = "Grant", Year = 2008 }
};
// Организация перебора массива анонимных типов
// (ключевое слово var обязательно).
foreach (var person in people)
Console.WriteLine("Person={0}, Year={1}", person.Name, person.Year);
Анонимные типы обычно используются с технологией языка интегрированных 
запросов (Language Integrated Query, LINQ), когда в результате выполнения запро-
са создается коллекция объектов, относящихся к одному анонимному типу, после 
чего производится обработка объектов в полученной коллекции. Все это делается 
в одном методе. В следующем примере все файлы из папки с моими документами, 
которые были изменены в последние семь дней:
String myDocuments = 
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var query =
from pathname in Directory.GetFiles(myDocuments)
let LastWriteTime = File.GetLastWriteTime(pathname)
where LastWriteTime > (DateTime.Now - TimeSpan.FromDays(7))
orderby LastWriteTime
select new { Path = pathname, LastWriteTime };
foreach (var file in query)
Console.WriteLine("LastWriteTime={0}, Path={1}", 
file.LastWriteTime, file.Path);
Экземпляры анонимного типа не должны выходить за пределы метода. В про-
тотипе метода не может содержаться параметр анонимного типа, так как задать 
анонимный тип невозможно. По тому же принципу метод не может возвращать 
ссылку на анонимный тип. Хотя экземпляр анонимного типа может интерпрети-
роваться как 
Object
(все анонимные типы являются производными от 
Object
), 
преобразовать переменную типа 
Object
обратно к анонимному типу невозможно, 
потому что имя анонимного типа на этапе компиляции неизвестно. Для передачи 
кортежного типа следует использовать тип 
System.Tuple
, о котором речь идет 
в следующем разделе.

Download 6,27 Mb.

Do'stlaringiz bilan baham:
1   ...   191   192   193   194   195   196   197   198   ...   658




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish