Определение пользовательских атрибутов
Класс атрибутов должен быть потомком
System.Attribute
Расширение языка
Доступно с помощью рефлексии .NET (System.Reflection)
obj.GetType().GetCustomAttributes(…);
Пример:
class PersonFirstNameAttribute : Attribute
{
public PersonFirstName()
{
}
}
(C) Сафонов В.О. 2012
C#: операторы
Операторы C# очень похожи на операторы C/C++Аналогичные C: управление и циклы
if (<bool expr>) { ... } else { ... };switch(<var>) { case <const>: ...; };while (<bool expr>) { ... };
for (<init>;<bool test>;<modify>) { ... };do { ... } while (<bool expr>);
В дополнение к C:
lock(<object>){ ... };
Синхронизация с помощью блокировщика, связанного с объектом
checked {...}; unchecked { ...}
Обработка целочисленного переполнения
unsafe {...}
Блоки для изоляции неуправляемого кода
(C) Сафонов В.О. 2012
C# 2.0: Параметризованные типы (generics)
История: Впервые введены в CLU (1974) как параметризованные
модули; включали параметры-типы и параметры-константы –
последние до сих пор не введены ни в C#, ни в Java
Цель: Разработка максимально общего повторно используемого кода для общеупотребительных коллекций – стеков. списков, деревьев, графов и др.
Пример:
public class Stack <ItemType> {
private ItemType items = new ItemType [100]; public void Push (ItemType data) { … }
public void Pop () { … } } …
Stack <int> s = new Stack <int> (); s.Push (3);
int i = s.Pop();
Могут быть определены ограничения на типы-параметры (тип- параметр должен реализовывать определенный набор интерфейсов)
(C) Сафонов В.О. 2012
C#: Встроенные коллекции и оператор foreach
Простая поддержка итераторов для коллекций
Может быть использована для массивов и любых других коллекций
Может также использоваться для классов, определяемых пользователем
Реализует IEnumerable через
GetEnumerator()
Возвращает объект, реализующий
IEnumeratorPoint[] Points = GetPoints();
foreach( Point p in Points )
Пример:
{
MyPen.MoveTo(p.x,p.y);
}
(C) Сафонов В.О. 2012
C#: Операции
Аналогичны C/C++ |
|
|
Как в C: |
|
|
Логические / условные : && || ^ |
||
арифметические: |
* / + - % << >> |
|
операции отношения: |
== != < > >= <= |
|
Не совсем как в C: |
|
|
для bool: & и | - по общей схеме (вычисляются оба |
||
операнда) |
|
|
для int: & и | выполняют поразрядное AND/OR |
||
Существенное дополнение к C (поддерживающее |
||
строгую типизацию): |
|
|
is |
Проверяет тип во время выполнения |
|
as |
Преобразует значение к заданному типу |
|
typeof Извлекает тип во время выполнения
(C) Сафонов В.О. 2012
C#: Перегрузка операций
Большинство операций могут быть переопределены (по аналогии с C++)
Арифметические, операции отношения, условные, логические операции
Перегрузка операций не допускается для:Оператора присваиванияСпецифических операций для контроля
типов (sizeof, new, is, typeof)
Пример:
Total operator +(int Amount, Total t)
{
t.total += Amount;
}
(C) Сафонов В.О. 2012
C#: перегрузка операций
(продолжение)
История: первым языком, в котором разрешалась
перегрузка операций, был ALGOL 68. В нем допускались и небезопасные перегрузки операций – не только самой
операции, но и ее приоритета (последнее могло приводить
к путанице и ошибкам - – представьте, например, что
операция “*” для матриц перегружена так, что имеет меньший приоритет, чем “+”!)
История: В C++ перегрузка операций введена с
разумными ограничениями. В C++ допускается
доопределение только самой операции, а не переопределение ее приоритета. Кроме того, перегрузка операций не должна приводить к конфликтам, т.е. не должно быть двух переопределений одной и той же операции с одними и теми же сигнатурами
Сравните: В Java, как можно предположить, с целью
упрощения языка и его реализаций, перегрузка операций
не допускается (разрешена лишь перегрузка методов)
(C) Сафонов В.О. 2012
C#: Доступ
Следуют модели C++ :
public вызов или доступ откуда угодноprotected только из подклассов
(соответствует модификатору “family” в CLI)
private достп только внутри текущего класса
Расширяют модель C+ :
sealed класс, от которого не допускается определение потомков (сравните: в Java ~ final)
internal доступ только из текущей сборки (CLI: “assembly”; Java: аналогов нет)
protected internal доступ только из подклассов, определенных в текущей сборке (CLI: “family and assembly”)
(C) Сафонов В.О. 2012
C#: указатели – управляемые и неуправляемые
C# поддерживает:
тип string
Гибкий механизм сборки мусора
Ссылочные аргументы (ref)
void increment(ref int value, int by)
Выходные аргументы (out)
bool add(int a, int b, out int c)
Не допускает “трюков” с указателями, разрешенных в C/C++
Неуправляемые указатели в стиле C/C++ разрешены в блоках unsafe:
unsafe void crypt(byte[] arr)
{
byte * b = arr;
...
}
(C) Сафонов В.О. 2012
C#: Boxing и Unboxing
Значения могут быть преобразованы в объектную форму (boxed) и обратно (unboxed)
Boxing – представление значения в виде объектаОсновано на объектном представлении всех типов
5 |
5 |
5 |
double Value;
// Boxing
object BoxedValue = Value; // Unboxing
Value = (double) BoxedValue;
Unboxed: Boxed: Копия Ссылка
(C) Сафонов В.О. 2012
C#: Сборка мусора 1/2
История: LISP (1960) – первый в мире язык со встроенным |
|
сборщиком мусора (до сих пор используется для задач |
|
символьной обработки и искусственного интеллекта) |
|
В C/C++ - приложениях очень часто возникают утечки памяти |
|
(memory leaks): |
|
|
*C p = new C(); … p = new C(); |
|
Распределение памяти “вручную” |
|
Нет явных правил принадлежности объектов |
COM: счетчик ссылок на объект |
|
|
Вызовы AddRef/Release должны быть сбалансированы |
|
“Умные” указатели не решают всех проблем |
В серверных приложениях вобоще не должно быть утечек |
|
памяти |
|
|
Должны работать месяцы и годы без единой утечки памяти |
Решение: автоматическое управление памятью (деструкторов нет)
Пользователям C++ : В среде .NET можно работать и “по- старому”, но для объектов, созданных в небезопасном коде, не будет выполняться сборка мусора
Сравните: В Java стратегия сборки мусора аналогична .NET
(C) Сафонов В.О. 2012
C#: Сборка мусора 2/2
Программист создает новые объекты и массивы данных
Память для них выделяется оператором new.NET Common Language Runtime автоматически отслеживает использование памяти
GC (Garbage Collector – сборщик мусора) автоматически удаляет все неиспользуемые объектыБолее эффективные методы управления памятью
Простые в использовании, не допускающие утечек памяти
(C) Сафонов В.О. 2012
C#: Недетерминированный процесс уничтожения объектов
Недостатки схемы, основанной на сборке мусора:
Финализаторы вызываэтся в какой-либо, заранее
не известный момент в будущем
Код финализатора не синхронизирован (т.е. не
МП-безопасен)
Разрыв с традициями C++
Внимание: Код не должен зависеть от деструкторов,
освобождающих внешние ресурсы
Вместо этого предлагается реализовывать интерфейс IDisposable, используя оператор using :
using( File f = new File("c:\\xyz.xml") )
{… }
IDisposable.Dispose() вызывается при выходе из блока
(C)Сафонов В.О. 2012
C#: Обработка исключений
Очень похожа на C++ и Java
Общая форма блока обработки исключений:
try исполнение-некоторого-кода ...
... если генерируется исключение,
catch (поймать) все, что можно обработать ...
...finally выполнить завершающие действия по освобождению ресурсов
Пример:
try
{
//... исполнение кода
}
catch(SomeException e)
{
//... обработка
} finally {
//... исполнить “последнее желание”
}
(C) Сафонов В.О. 2012
C#: Основные отличия от
C++
C# внешне очень похож на C/C++В C# ликвидированы многие источники ошибок:
Более строгий контроль типов и приведения
Отсутствует “проваливание” (fall-through)
вswitch-операторе
Булевские выражения строго типизированы
Отсутствуют заголовочные файлы (.h,
.hpp)
”Почти нет указателей” “почти нет ошибок”
Отсутствуют утечки памяти
(C)Сафонов В.О. 2012
C#: Управление версиями классов
Реалистичный пример:
А и В независимо разрабатывают приложения
Класс A базируется на классе B
B реализует метод CalcResult
В следующей версии A также реализует
CalcResult
Вопрос: Хочет ли B, чтобы его CalcResult
переопределял метод из A ?
Ответ: Маловероятно.
Решение (C#): Явно сформулировать цели использования наследования:
override – переопределить метод
new virtual – избежать наследования от базового класса
Сравните: Ни в C++, ни в Java таких возможностей нет.
(C) Сафонов В.О. 2012
C#: XML-комментарии
Встроенная функциональность для документирования кодаКомментарии с "///" экспортируются
Компиляция с опцией /doc -> генерируется XML- документация
Имеет предопрелеленную схему
Сравните: В Java приходится использовать утилиту командной строки javadoc для генерации HTML- (а не
XML-) документации на основе документирующих комментариев///<summary>
///Пример:This function serves to calculate the
/// overall value of the item including all
/// taxes
/// </summary>
/// <remarks>
/// Tax calculates in CalcTax()
/// </remarks>
public decimal GetTotalValue()
{
}
(C) Сафонов В.О. 2012
C#: Инструменты программирования .NET
.NET Framework SDK (интерфейс командной строки)
C# - компилятор
Визуальный отладчик
Nmake – инструмента для сборки проектовVisual Studio.NET (новейшая версия - VS.NET 2008)
Интегрированная среда, очень удобная для разработки приложений на C#
Шаблоны и “мастера” кода для различных видов приложений (консольных, Web- приложений и др.)
Интеллектуальный help
(C) Сафонов В.О. 2012
