
- •Оглавление
- •Об авторе
- •Посвящение
- •Благодарности
- •Ждем ваших отзывов!
- •Что такое .NET
- •Создание исходной программы
- •Тестовая поездка
- •Каркас программы
- •Комментарии
- •Введение в хитрости панели элементов
- •Повторное использование кода из панели элементов
- •Правила объявления переменных
- •Вариации на тему int
- •Объявление переменной с плавающей точкой
- •Ограничения переменных с плавающей точкой
- •Объявление переменных типа decimal
- •Сравнение десятичных и целых чисел, а также чисел с плавающей точкой
- •Логичен ли логический тип
- •Символьные типы
- •Что такое тип-значение
- •Неизменяемость строк
- •Основные операции над строками
- •Сравнение строк
- •Сравнение без учета регистра
- •Отличие строк в разных регистрах
- •Преобразование символов строки в символы верхнего или нижнего регистра
- •Поиск в строках
- •Как искать
- •Пуста ли строка
- •Удаление пробельных символов
- •Анализ числового ввода
- •Обработка последовательности чисел
- •Объединение массива строк в одну строку
- •Арифметика
- •Простейшие операторы
- •Порядок выполнения операторов
- •Оператор инкремента
- •Сравнение чисел с плавающей точкой
- •Составные логические операторы
- •Вычисление типа операции
- •Типы при присваивании
- •Перегрузка операторов
- •Ветвление с использованием if и switch
- •Инструкция if
- •Инструкция else
- •Как избежать else
- •Вложенные инструкции if
- •Конструкция switch
- •Циклы
- •Цикл без счетчика
- •Правила области видимости
- •Пример
- •Зачем нужны разные циклы
- •Зачем нужны массивы
- •Массив фиксированного размера
- •Массив переменного размера
- •Свойство Length
- •Инициализация массивов
- •Понятие <т>
- •Обобщенные коллекции
- •Инстанцирование пустого списка
- •Создание списка целых чисел
- •Преобразования списков в массивы и обратно
- •Подсчет количества элементов в списке
- •Поиск в списках
- •Инициализаторы массивов и коллекций
- •Выполнение специфичных для множеств задач
- •Создание множества
- •Добавление элемента в множество
- •Выполнение объединения
- •Пересечение множеств
- •Получение разности
- •Не используйте старые коллекции
- •Обход каталога файлов
- •Начало программы
- •Получение начальных входных данных
- •Создание списка файлов
- •Форматирование вывода
- •Вывод в шестнадцатеричном формате
- •Обход коллекций: итераторы
- •Доступ к коллекции: общая задача
- •Использование foreach
- •Формат индексатора
- •Блок итератора
- •Создание каркаса блока итератора
- •Итерирование дней в месяцах
- •Что же такое коллекция
- •Синтаксис итератора
- •Блоки итераторов произвольного вида и размера
- •Обобщенные классы безопасны
- •Обобщенные классы эффективны
- •Очередь с приоритетами
- •Распаковка пакета
- •Написание обобщенного кода
- •Использование простого необобщенного класса фабрики
- •Незавершенные дела
- •Ковариантность
- •Использование механизма исключений для сообщения об ошибках
- •Что происходит при генерации исключения
- •Исключительный пример
- •Что делает этот пример "исключительным"
- •Трассировка стека
- •Советы по написанию кода с хорошей обработкой ошибок
- •Анализ возможных исключений метода
- •Как выяснить, какие исключения генерируются теми или иными методами
- •Генерирующие исключения выражения
- •Работа с перечислениями
- •Создание перечислений с инициализаторами
- •Указание типа данных перечисления
- •Применение перечислений в конструкции switch
- •Процедурные поездки
- •Объектно-ориентированные поездки
- •Определение класса и объекта
- •Определение класса
- •Что такое объект
- •Различие между объектами
- •Работа со ссылками
- •Классы, содержащие классы
- •Определение константных членов-данных и членов-данных только для чтения
- •Передача аргументов методу
- •Передача методу нескольких аргументов
- •Соответствие определений аргументов их использованию
- •Перегрузка методов
- •Реализация аргументов по умолчанию
- •Возврат значения оператором return
- •Кортеж с двумя элементами
- •Создание кортежей более чем с двумя элементами
- •Глава 14 Поговорим об этом
- •Определение методов
- •Определение статического метода
- •Определение метода экземпляра
- •Полное имя метода
- •Ключевое слово this
- •Когда this используется явно
- •Что делать при отсутствии this
- •Использование локальных функций
- •Прочие уровни безопасности
- •Методы доступа
- •Пример управления доступом
- •Выводы
- •Статические свойства
- •Побочные действия свойств
- •Дайте компилятору написать свойства для вас
- •Методы и уровни доступа
- •Замена конструктора по умолчанию
- •Конструирование объектов
- •Непосредственная инициализация объекта
- •Конструирование с инициализаторами
- •Инициализация объекта без конструктора
- •Определение свойств с кодом
- •Определение конструкторов и деструкторов с кодом
- •Определение методов доступа к свойствам с кодом
- •Определение методов доступа к событиям с кодом
- •Наследование класса
- •Более сложный пример наследования
- •ЯВЛЯЕТСЯ или СОДЕРЖИТ
- •Доступ к BankAccount через содержание
- •Отношение СОДЕРЖИТ
- •Заменяемость классов
- •Неверное преобразование времени выполнения
- •Указание конкретного конструктора базового класса
- •Обновленный класс BankAccount
- •Перегрузка унаследованного метода
- •Простейший случай перегрузки метода
- •Различные классы, различные методы
- •Сокрытие метода базового класса
- •Вызов методов базового класса
- •Что неверно в стратегии использования объявленного типа
- •Использование is для полиморфного доступа к скрытому методу
- •Объявление метода виртуальным и перекрытие
- •Получение максимальной выгоды от полиморфизма
- •Разложение классов
- •Абстрактный класс: ничего, кроме идеи
- •Как использовать абстрактные классы
- •Создание абстрактных объектов невозможно
- •Опечатывание класса
- •Реализация интерфейса
- •Именование интерфейсов
- •Наследование и реализация интерфейса
- •Преимущества интерфейсов
- •Тип, возвращаемый методом
- •Что скрыто за интерфейсом
- •Гибкие зависимости через интерфейсы
- •Реализация отношения СОДЕРЖИТ с помощью интерфейсов
- •Определение делегата
- •Пример передачи кода
- •Делегирование задания
- •Очень простой первый пример
- •Более реальный пример
- •Создание приложения
- •Жизненный цикл делегата
- •Анонимные методы
- •Проектный шаблон Observer
- •Что такое событие. Публикация и подписка
- •Как издатель оповещает о своих событиях
- •Как подписаться на событие
- •Как опубликовать событие
- •Как наблюдатели "обрабатывают" событие
- •Сборки
- •Выполнимые файлы
- •Библиотеки классов
- •Создание проекта библиотеки классов
- •Создание автономной библиотеки классов
- •Создание классов для библиотеки
- •Использование тестового приложения
- •Дополнительные ключевые слова для управления доступом
- •protected: поделимся с подклассами
- •protected internal: более изощренная защита
- •Размещение классов в пространствах имен
- •Объявление пространств имен
- •Пространства имен и доступ
- •Использование полностью квалифицированных имен
- •Ссылочные типы
- •Выходные параметры
- •Альтернативные методы возврата значений
- •Работа с переменными out
- •Возврат значений по ссылке
- •Различия типов-значений
- •Когда следует использовать структуры
- •Добавление распространенных элементов структур
- •Управление отдельной записью
- •Добавление структур в массивы
- •Перекрытие методов
- •Определение того, что следует защищать
- •Документирование компонентов программы
- •Разложение компонентов на функции
- •Оценка рисков
- •Аутентификация с использованием входа в Windows
- •Безопасность развертывания
- •Уязвимости сценариев
- •Наилучшие методы защиты приложений Web Forms
- •Получение данных
- •Настройка образца схемы базы данных
- •Подключение к источнику данных
- •Работа с визуальными инструментами
- •Написание кода для работы с данными
- •Использование Entity Framework
- •Где водится рыба: файловые потоки
- •Потоки
- •Читатели и писатели
- •Пример использования потока
- •Как это работает
- •Наконец-то мы пишем!
- •Использование конструкции using
- •Загрузка файла из Интернета
- •Регистрация сетевой активности
- •Графика
- •Перья
- •Кисти
- •Текст
- •Классы рисования и каркас .NET
- •Приступая к работе
- •Настройка проекта
- •Обработка счета
- •Создание подключения к событию
- •Рисование доски
- •Запуск новой игры

,iВВТОhЕТИЕТВПTИНИНОcИСПИЕ!ИiО!СЕТАЕТT iООИЕ!НСhВНИВЗtСnЕBК.ti мСsТЕХ ООЕТОiОЕВ!НСhСВЕТЕТО!В hЕТОИ СT TW a МНОА ВtОЕТiBВНВВТОННЕТНВТССT !ИПTНО
|
СОВЕТ |
|
|
>АЕТСЕТИС!АВ ОАЕТСПTНЕВТИТЕВСННЕХ! БЕТОИtПС!В c DC u |
aT o;,aCcCD |
О |
ChСЕТо04CiООО!ЕИЕТИТoОООЕТОiОЗЕТОПВВТОВiОЕТНОBВВЕТiСААОСЕ!СНО! tПС!В -n-ВЕТ |
|
нiСЕТОЕТСАОАЕТiООСЗИЕТИТОЗo04 oЕ!НСhВНИВЗНВН!ПНВЕТАН |
|
Что такое тип-значение
ТЕХНИЧЕСКИЕ
поДРОБНости
ЗАПОМНИ!
й$1t1_ |
1t1"'1"(,1"'1'1,__ |
!1t1$1#'1 |
'1," |
. T,!. |
1,#."_ |
$(,1"х, |
S$,1$J1!.#'1'1,. |
||
J1# |
(,1"J1 |
#$1, ,х."'1$"(,1 |
,$1t1# |
,'1N'1#_w f\41"J1"(,1"'1'1," |
,$1t1!. |
1 1t1!1,! |
|||
-'1'1,(,1 |
J1# |
(,1"J1!(,1 .1"1,# |
#'1$(,1#х, !,'1! |
$ ,! |
." ,!,$ |
."1,.! |
1t1#(,1-,$JJ |
||
БОпчБ пчБозББз ББНББ |
|
ДРО,зАРпАчАДРОАоРБРт БНБмАБНБАз |
ИИ оТИ!оТМИМЕНБ!ОоО!ИМОИ!НИСБ ЕИТp ИИОЗБО!МЕСБ оТМТНЗООИ И ОМоНЕМоИТИЕИИИОЧОТНТЕЕИТН-. ТОЕИ ООЧО.pОМ !М!С оИТИЕИИИСБ
БТНИБОИБ! ИоИСМННИОЕ! ЕИИОИоО! ИНТЕ!НИМИЕ\0,.s ПНП!Н ММИИПМИ ТЕИНМИИМБ!НЕ. ИИИЕ!ИО ЗИИоОПОМОНИБИОИПИоТОИООИЕ!ИО ТЕИНОНp МОООИИЕЧИИО!ЕИОПНПЕИИООо!О!ИИМИ ! оНЕБОМ\dОН БНТНПОИТМИОМП
ПНоОБИИБИОpоОМИЕЕ!НИИСИ ОМоСИНТЕС!НeОИБ0. s . |
SDСm. ,.S. |
o ..c МА.l!1db. |
|
МоС,.НesЕМ! О ХММeМ МБ •З!МТЕПМИТО!ИО!ИИИМПМrИНоО!ОЗМИ ЗИТЕТЕИНПО!ОЧОGНН Б!!БeОИБ !ИОТОИИИСЕМ o! оНОСИИИОТ!1ОМоНЕМ. !ИОТОИИИaИОМоСоИТИЕИИИСБ М ОМо,ОЕ РООИ! МТЕ!ИИОИСОНП!И ПНП ОМоСoТЕИНМИИPМБо. СНЗGНeИИООИОИМОИМПБ ОИЕ ИМП !НЕЧМЕpоО ИПОЕТНПЕоИТИЕИИИНББТНИМОИБ! !М!И ИИПОООТОЧО•ЕПНТЕНОИ!БИНr !НИП ИСИТПОООТСЗИНТЕС!НИОИБ\\МАОСТИo\s". .\ .On.!1ТЕХFSТSНИИСИОНПОЗИОТОПМ ИН ИНЕОЕ !И!И ТНИоО!НЧНeОИБ! !ТЕЧОЕ ЕИИОИТЕХ!ИО оТИ!ИОН!МОН ИИС!ОМИСЗ ОМоПНПН!ТИИ!ОЕН. oИНИМИН!ТИИН!НИО!НЕ МИ!ОТЕНСМe
ОООЕpЧ!И ИНБО!МОИБ!ОЕp ИОМООЗС!ООММeИЧОЕ!М!ИОНpИЕ!ИО оОЗОМ оО!НИИОЕЕ Н!ТИИЕТЕХ
PМоСpО ПОООТСБТИМНоОЗ!ИО! Ч!Н!И e: •Е!ЗОЗЧИИИОИОН ОоТИp !И!БИЕСИ оТОЧТНЕЕМИООЕММТЕ!ИИОИСИПНПИИС!ОМИСИОМоСИИБ!!БeОИБ ИМ!ИОТОИИИС ЕМ. ИМОМоНЕМ ТЕИНМИИМБЕМPМо СНЗn GНeБ!!БИОИБ ИИС!ОМИСЕpБООБПОЕоМ!Бe ООТА, ТНИИЕНОТМ!НИОИЧОИоИСМН!НИСЕОЗТНТЕОЕ! ИМ!Е ИЧОТМТОПОЗТНИоТОП ИОТНИИИИОИОМТЕХ
..С ЧАСТЬ 1 |
Ч)(Г |
.( .0ВВ1. (Г0)1 )0 |

равJtение string и chax- |
|
|||
,1;1ni1;1.,_, |
i,i1;1,n1;1 ,r i,BJt,Ж,Jt |
1;1,а |
string ьб.еьвмерро овжа)иевья ов |
|
вали char. борявроз )во анетвья ретовоспе всамаижeрпе овжа)аяЧ аит ьане |
||||
можоитжт)иевья модарисрпе тимп)та rи ьвсоти a |
м дмоарпеtосоне вороsвал |
|||
char - кво мьердиодар ьанмож; вит )во ьжедбт.аа |
тод ре анеев ьнпьжи ра м |
|||
лжиреьжойерая; ра млжиретортиверираач |
|
bL |
b |
A |
и |
bL |
|
м |
|
bL |
|
|
b |
м
бк t
б
A
машисдаАгсац нeжть aeтц
ои ьинон дежеквов тод ло)ва тонлажасбен2 ро ероьнпьж ьб.еg |
|
ьвмерроовжа)иевья ов вороетовоспа нп енб лсалаь пмиенелопт вп |
|
лсеозсиобев cl а с2 мори)ерая вали int, лседьвимжят.ае |
ьозоа )аь, |
жомпеори)ерая ьоовмевьвмбт.ас ьанможом;лоьже )еро ьтжидпмиев |
|
ложб)еррпе ори)ераяедаазти мооратиевлса лолпвте ьоссиравe лое |
|
жб)еррпа сеобжeвивм сЗ, вит тит лса сионе.ераа ори)ерая вали int |
|
млесенерроа нерeаеро сионеси char диррпе норбв зпвe |
ловесярпе |
хжтзон ьжб)ие кви олесирая ре анеев ьнпьжиt
вдсброаьвосорпWьвсоти нойев зпвe жтзоа джарпЧитан озсиоон; тортие верирая дмбсьвсот мложреоьнпьжерриг
·w н н б
· |
w · |
AQ н |
бн |
бA uu |
o н |
н |
w |
Q |
м |
||||
х |
ти)еьвме )иьва ьмоеазазжаовета вп олседежяеврежпа сяд ьвсотомпс |
|||||
олесирааWтовоспе збдбв олаьирп |
мржимер; юцизови ьо ьвсотинадt |
СОВЕТ
Программирование - и так достаточно сложное дело, чтобы услож нять его еще больше. Чтобы код на С# было легче читать, обычно ис
пользуются определенные соглашения об именовании переменных, которым желательно следовать, чтобы код был понятен другим программистам.
•
Имена всех объектов, кроме переменных, начинаются с прописной буквы, а имена переменных - со строчной. Делайте эти имена как мож
но более информативными (зачастую это приводит ктому, что имена состо ят из нескольких слов). Слова для объектов, не являющихся переменными, должны начинаться с прописной буквы, и лучше, если между ними не будет символов подчеркивания, например ThisisALongName.
ГЛАВА 2 |
Работа с переменными |
61 |

•Имена переменных отличаются только тем, что первая буква - строч-
ная: thisisALongVariaЬleName.
До эры .NET использовалось соглашение, в соответствии с которым первая буква имени переменной указывала ее тип (так называемая "венгерская за пись"). Большинство таких букв тривиальны: f - для float, d - для douЫe, s - для string и т.д. Исключением из правила является n для int. Есть еще одно исключение: по традиции, уходящей в программирование на Фортране, буквы i, j и k также используются как распространенные имена переменных типа int.
Венгерская запись постепенно выходит из моды, по крайней мере в кругах про граммистов .NET. Тем не менее я все еще остаюсь ее поклонником, поскольку она позволяет мне знать тип каждой переменной в программе, не обращаясь к ее объявлению. В последних версияхVisual Studio вы можете просто подвести курсор к переменной и получить информацию о ее типе в окне подсказки, что делает венгерскую запись менее полезной. Однако вместо того, чтобы встре вать в "религиозные войны" по поводу того или иного способа именования, выберите тот, который вам по душе, и следуйте ему.
Вычисление високосных лет: "'1. ,(,1 '1, ).
(! если вам нужна программа для выяснения, является ли некоторый год високосным?
Вот алгоритм для поставленной задачи:
t |
зt |
, |
•ййt |
зййб |
Пока что вы не знаете, как перевести это на язык С#. Но можно просто спросить тип DateTime о том, високосный ли некоторый год (тип DateTime яв ляется типом-значением наподобие int):
aK |
l·- |
l |
· .lK Q |
l aK l-l· оAй••t•t |
• sб |
] |
· |
ыlK |
.lK Q aK |
l·-lс ВыlK .lK с · |
.lK с.lK s б |
Результат для 201 6 года - true, для 201 7 - false. (Пока что не обращайте внимания на первую строку кода.)
Тип DateTime позволяет выполнять около 80 разных операций, например получение названия месяца и дня недели; добавлен ие дней, часов, минут и так далее к конкретной дате; получение количества дней в месяце; вычитание двух дат.
62 |
ЧАСТЬ 1 Основы программирования на С# |

=
=
= ==t-= *= E*=;tg=E=*E*=*==a*n-=t;t;E-
=
=
= ===aE==;tg = == *=t==E=A ; E= *= =-=;EA T ; t;E==
=
= |
|
nsnnros |
|
|
|
=*-==-=5+*==)-=== |
==+)+=*=5g= |
==5)= =*-= )= |
t ==g=l)==-= ====- |
==+ |
*=== =) |
+= h==5+h)) ;= )A=5+-*=-= =+)A==+5=)+-=-==+=-*=-==)-=g==
==-==+==*) ==-=l) ; |
55= |
= |
=-= |
-+=*=-= |
) =*) ==-=l) |
||
+*=-= |
|
*=+h=5+*===g5+===- |
)-=*====+ =)+= h==5+h *=-=== |
||||
=-=g = A=5=- g =-)=g+) =g = 5=;g== =+-=*+==5+*======- |
|||||||
==+m+g=*=== =)+==5h===h |
=;+g |
=*==5+=- |
== +=;gl)=- |
||||
-=-==+-*=-==) ===+ =-== |
=;+ |
=*==5+=- |
==l)=-* -A=*== |
||||
+*) = |
==5 |
+=;gl=G= |
)= |
)= =*)==- |
==)= = |
===+ |
|
=A)+= |
)= |
=
= |
= |
= |
= |
=*-==5+*=;=5=====*===+ |
=)+= h- =5+hA=5- =*== gA==+-*=-=) |
====- ;===+-gm+=+A=5 ==5 |
==g)E5+*=;= A=5=+-==--h=A)+==+5= |
ГЛАВА 2 Работа с переменными |
63 |

Объя',влен, 'l, ,,,ие,(),чис,, л,, овых"1(,
СТрw1К,от,Вт ,, .#',,:з , . ВТ
кТонстантВТ Н
М, ),(Т _ Г Н , _ "1 Т ,s_ ,sО,зТ dТ
#Т,-Т |
'lТ |
i,Т |
-JТ.Т-Т:p |
op
В жизни очень мало абсолюта, но он присутствует в С#: любое выражение имеет значение и тип. В объявлении наподобие int n легко увидеть, что пере менная n имеет тип int. Разумно предположить, что тип результата вычисле ния n+1 - также int. Но что можно сказать о типе константы 1?
Тип константы зависит от ее значения и наличия необязательной буквы в конце. Любое целое число величиной примерно до 2 миллиардов (см. табл. 2.1 ) рассматривается как int. Числа, превышающие это значение, трактуются как long. Любые числа с плавающей точкой рассматриваются как douЫe.
В табл. 2.4 показаны константы, объявленные как имеющие конкретные типы, т.е., в частности, с буквенными дескрипторами в конце. Строчные эти буквы или прописные - значения не имеет, например записи lu и lU равно ценны.
Таблица 2.4. Объявление констант с их типом
Константа
1 lU lL
1 . 0
ч а яо, lM true false
э e э n
'\n '
'\х123 '
"а string"
вс ю
Тип
int unsigned int
long int (избегайте использования строчной 1 - она слишком похожа на единицу, 1)
douЬle float decimal bool bool char
char (символ новой строки)
char (символ с шестнадцатеричным числовым значением 1 23) string
string (пустая строка)
64 |
ЧАСТЬ 1 Основы программирования на С# |

Преобразо,_вание ипо_в
Человек не рассматривает числа, используемые для счета, как разнотипные. Например, нормальный человек (не программист на С#) не станет задумывать ся, глядя на число 1, знаковое оно или беззнаковое, "короткое" или "длинное". Хотя для С# все эти типы различны, даже он понимает, что все они тесно свя заны между собой. Например, в приведенном далее фрагменте исходного тек ста величина типа int преобразуется в long:
:им :им cщr = ,
=
Переменная типа int может быть преобразована в long, поскольку любое значение типа int может храниться в переменной типа long и оба типа пред ставляют собой числа, пригодные для перечислений. С# выполняет это преоб разование автоматически, без каких-либо комментариев. Такое преобразование типов называется тl?,т(Р (implicit).
Однако преобразование в обратном направлении может вызвать проблемы. Например, приведенный далее фрагмент исходного текста содержит ошибку:
rсим1 rсим1cщr , |
:pW |
|
||
:им |
:им |
crщ ,W |
rсим1cщr ,W цц |
е |
:им |
cщr |
, |
Некоторые значения, которые могут храниться в переменной long, не помещаются в переменной типа int (ну, например, 4 миллиарда). С# в такой ситуации генерирует сообщение об ошибке, поскольку в
СОВЕТ процессе преобразования данные могут быть утеряны. Ошибку тако го рода обычно довольно сложно обнаружить.
Но что если вы точно знаете, что такое преобразование вполне допустимо? Например, несмотря на то что переменная longValue имеет тип long, в данной конкретной программе ее значение не может превышать 1 0 0 . В этом случае преобразование переменной longValue типа long в переменную intValue типа int совершенно корректно.
Вы можете пояснить
14 2,lH lт2{ e21л,e
С#, что отлично понимаете, что делаете, посредством
rсим1 rсим1cщr ,=
При приведении вы непосредственно перед
размещаете имя требуемого типа в круглых скобках преобразуемым значением. Приведенная выше запись
ГЛАВА 2 Работа с переменными |
ейн |

гласит: "Не волнуйся и преобразуй longValue в тип int - я знаю, что делаю, и всю ответственность беру на себя". Конечно, такое утверждение в ретроспек тиве может оказаться излишне самоуверенным, но зачастую оно совершенно справедливо.
Перечислимые числа могут быть преобразованы в числа с плавающей точ кой автоматически, но для обратного преобразования необходим оператор при ведения типов, например:
,р |
, ,р |
r,cшr =, |
|
|
= |
Все приведения к типу decimal и из него нуждаются в операторе приведе ния типов. В действительности все числовые типы могут быть преобразова ны в другие числовые типы с помощью такого оператора. Однако ни bool, ни string не могут быть непосредственно приведены ни к какому иному типу.
Встроенные методы С# могут преобразовывать числа, символы или логические переменные в их строковые "эквиваленты". Например, вы можете преобразовать значение true типа bool в строку "true ";
подРоБdр(lбзiбк нОСТJ.1 однако такое преобразование нельзя рассматривать как непосред- ственное. Эти два значения - совершенно разные вещи.
Позвольте компилятору С# вывести типы_ данн1:»_1х
Пока ную, мы
что
,)l
везде в этой книге - ну Hз указывали ее точный
ладно, в этой главе, - объявляя перемен
тип:
:им |
: . |
й e |
,р |
имх:1 |
. у I,rnrр тр e |
r, , |
= |
Но можно переложить часть работы на плечи компилятора С#, воспользо вавшись ключевым словом var:
var i = |
5 ; |
T = |
|
var |
= |
= |
|
var |
= |
|
В этом случае компилятор сам ,(,лHг1 что находится в правой части присваивания
ется в левой части.
,
тип данных - он смотрит на то, чтобы выяснить, какой тип требу
ъъ, |
ЧАСТЬ 1 тcеотни ж»ощ»ряяв» отревеи ериС# |

В главе 3, " Работа со строками", рассматривается, как выч исляется тип выражений наподобие приведенных выше. Но такая информация
вам, скорее всего, не понадобится - компилятор со всем справится подРоБностиТЕХНИЧЕСКИЕ и без вас. Предположим, например, что есть инициализирующее вы-
ражение наподобие
=
Компилятор в состоянии вывести, что х - значение типа douЫe. О н видит е иО еи 1 . 5 и знает, что они имеют тип douЬle. Затем он видит, что 2 имеет тип int, который ком пилятор может .и сe.уmконвертировать в douЫe для выполне ния вычислений. В результате все члены выражения инициализации перемен ной х имеют тип douЬle, так что eеeифи..есm йтиmх также представляет собой douЬle.
Так что теперь для объявления переменной достаточно ключевого слова var и инициализирующего выражения, остальное компилятор сделает сам :
=
Есл и вы работали с такими языками сценариев, как JavaScript или VВScгipt, то вы должны были испол ьзовать тип данных "все в одном". В VBScript такой тип данных называется Variant - тип данных, ко
; торый может быть чем угодно. Не является ли var в С# обозначени- ем типа данных Variant? Ни в коем случае. Объект, объявленный с применением ключевого слова var, олиийmуиrифDи..есm йтиmфг..еim С#, такой как int, string или douЫe. Вы просто не объявляете его.
Чем же в действительности являются переменные, объявленные как var? Давайте взглянем на следующий фрагмент кода:
= = |
T = |
Здесь инструкция WriteLine вызы вает метод St ring . GetType ( ) объекта astring, чтобы получить его тип данных С#. Затем для полученного объекта вызывается метод ToString ( ) , позволяющий вывести название типа. Вот по чему в окне консоли вы увидите
Это доказывает корректный вы вод типа переменной aString.
В большинстве случаев не стоит использовать ключевое слово var. Оставьте его на те случаи, когда это необходимо. Я вное указан ие типа переменной делает исходный текст понятнее любому, кто будет
СОВЕТ |
его читать. |
|
|
Р |
абота с переменными |
тн |
ГЛАВА 2 |
|
е |

Н иже будут приведены примеры, в которых применение бел совершенно необходимо, так что я буду использовать его во многих местах книги - часто даже там, где без него, строго говоря, можно было бы обойтись. Посмотрев на примеры, вы сами решите, как и когда применять это ключевое слово.
|
Вы можете встретить различные применения ключевого слова тегщ |
|
например, с массивами или коллекциями данных (глава 6, "Глава для |
СОВЕТ |
коллекционеров") или с анонимными типами (часть 2, "Объектно |
ориентированное программирование на С#"). |
Начиная с С# 4.0 типы становятся еще более гибкими, чем бегc тип рк-е,ая делает по сравнению с тег шаг вперед.
Тип тег заставляет компилятор вывести тип переменной на основе ожидае мых вводимых данных. Ключевое слово ркае,(л делает это во время выполне ния, используя и нструментарий под названием "Dynamic Laлguage Runtime". Дополнительную информацию о ркае,нл вы найдете в части 3, "Вопросы про ектирования на С#".
юоС ЧАСТЬ 1 тйеотни жаощарааваот рев еиерииси

Ра б ота со ст р о ка м и
|
б |
в |
|
|
ВВ |
й |
|
1 |
|
ВВ |
О |
П |
п |
ф |
ВВ |
|
|
|
|
ВВ |
а С |
у |
|
|
1Во м ногих приложениях тип м акнат можно рассматривать как один из |
||||
|
встроенных типов-значений наподобие наа или лтчкg К строкам приме |
|||
|
нимы некоторые из операций, зарезервированных для встроенных ти |
|||
пов, |
например: |
|
|
|
=
==
Вдругих отношениях, как видно из приведенного далее фрагмента, строки можно рассматривать как пользовательский класс (о классах речь пойдет в раз
деле 2, "Объектно-ориентированное программирование на С#"):
=
==
=
Так что же такое макнат Ч тип-значение или класс? На самом деле оакнат v это класс, который в силу ero ш ирокой распространенности С# трактует специ альным образом. Например, ключевое слово макнат является синонимом имени класса оак,атt как видно из следующего фрагмента исходного текста: