- •Введение Обзор .Net. Основные понятия
- •Программа на c#
- •Основы языка Пространство имён
- •Система типов
- •Класс и Структура. Первое приближение
- •Литералы. Представление значений
- •Арифметические литералы
- •Логические литералы
- •Символьные литералы
- •Символьные escape-последовательности
- •Строковые литералы
- •Операции и выражения
- •Приоритет операций
- •Приведение типов
- •Особенности выполнения арифметических операций
- •Особенности арифметики с плавающей точкой
- •Константное выражение
- •Переменные элементарных типов. Объявление и инициализация
- •Константы
- •Перечисления
- •Объявление переменных. Область видимости и время жизни
- •Управляющие операторы
- •Синтаксис объявления метода
- •Вызов метода
- •Перегрузка методов
- •Способы передачи параметров при вызове метода
- •Передача параметров. Ссылка и ссылка на ссылку как параметры
- •Сравнение значений ссылок
- •This в нестатическом методе
- •Свойства
- •Обработка исключений
- •Массив. Объявление
- •Инициализация массивов
- •Примеры инициализации массивов
- •Два типа массивов: Value Type and Reference Type
- •Встроенный сервис по обслуживанию простых массивов
- •Реализация сортировки в массиве стандартными методами
- •Подробнее о массивах массивов (jagged array)
- •Массивы как параметры
- •Спецификатор params
- •Main в классе. Точка входа
- •Создание объекта. Конструктор
- •Операция new
- •В управляемой памяти нет ничего, что бы создавалось без конструктора
- •Кто строит конструктор умолчания
- •This в контексте конструктора
- •Перегрузка операций
- •Синтаксис объявления операторной функции
- •Унарные операции. Пример объявления и вызова
- •Бинарные операции
- •Определение операций конъюнкция и дизъюнкции
- •И вот результат…
- •Пример. Свойства и индексаторы
- •Explicit и implicit. Преобразования явные и неявные
- •Наследование
- •Наследование и проблемы доступа
- •Явное обращение к конструктору базового класса
- •Кто строит базовый элемент
- •Переопределение членов базового класса
- •Наследование и new модификатор
- •Полное квалифицированное имя. Примеры использования
- •Прекращение наследования. Sealed спецификатор
- •Абстрактные функции и абстрактные классы
- •Ссылка на объект базового класса
- •Операции is и as
- •Виртуальные функции. Принцип полиморфизма
- •Интерфейсы
- •Делегаты
- •События
- •События и делегаты. Различия
- •Атрибуты, сборки, рефлексия Рефлексия (отражение) типов
- •Реализация отражения. Type, InvokeMember, BindingFlags
- •Атрибуты
- •Сборка. Класс Assembly
- •Класс сборки в действии
- •Разбор полётов
- •Класс System.Activator
- •Версия сборки
- •Файл конфигурации приложения
- •Общедоступная сборка
- •Игры со сборками из gac
- •Динамические сборки
- •Динамическая сборка: создание, сохранение, загрузка, выполнение
- •Ввод-вывод Базовые операции
- •Потоки: байтовые, символьные, двоичные
- •Предопределённые потоки ввода-вывода
- •Функция ToString()
- •Консольный ввод-вывод. Функции-члены класса Console
- •Консольный вывод. Форматирование
- •Функции вывода. Нестандартное (custom) форматирование значений.
- •Консольный ввод. Преобразование значений
- •Файловый ввод-вывод
- •Потоки Процесс, поток, домен
- •Домен приложения
- •Обзор пространства имён System.Threading
- •Многопоточность
- •Виды многопоточности
- •А кто в домене живёт…
- •Класс Thread. Общая характеристика
- •Именование потока
- •Игры с потоками
- •Характеристики точки входа дополнительного потока
- •Запуск вторичных потоков
- •Приостановка выполнения потока
- •Отстранение потока от выполнения
- •Завершение потоков
- •Метод Join()
- •Состояния потока (перечисление ThreadState)
- •Одновременное пребывание потока в различных состояниях
- •Фоновый поток
- •Приоритет потока
- •Передача данных во вторичный поток
- •Извлечение значений (данных) с помощью Callback методов
- •Организация взаимодействия потоков
- •1. Посредством общедоступных (public) данных
- •2. Посредством общедоступных (public) свойств
- •3. Посредством общедоступных очередей
- •Состязание потоков
- •Блокировки и тупики
- •Очереди. Основа интерфейса взаимодействия
- •Безопасность данных и критические секции кода
- •Пример организации многопоточного приложения
- •Очередь как объект синхронизации
- •Синхронизация работы потоков при работе с общими ресурсами
- •1. Организация критических секций
- •2. Специальные возможности мониторов
- •Рекомендации по недопущению блокировок потоков
- •Форма Класс Form
- •Форма: управление и события жизненного цикла
- •Форма: контейнер как элемент управления
- •Разница между элементами управления и компонентами.
- •Свойства элементов управления. Anchor и Dock
- •Extender providers. Провайдеры дополнительных свойств
- •Validating и Validated элементов управления
- •Управление посредством сообщений
- •Стандартный делегат
- •Делегат EventHandler
- •Класс Application
- •События класса Application
- •Примеры перехвата сообщений
- •Метод WndProc
- •Пример переопределения WndProc
- •Контекст приложения
- •Применение классов GraphicsPath и Region. Круглая форма
- •Собственные элементы управления
- •Литература
Определение операций конъюнкция и дизъюнкции
Операторные функции конъюнкция и дизъюнкция объявляются только полсе того, как объявлены операторы true и false.
public static Point2D operator | (Point2D par1, Point2D par2)
{
if (par1) return par1;
if (par2) return par2;
else return new Point2D(-1.0F, -1.0F);
}
public static Point2D operator & (Point2D par1, Point2D par2)
{
if (par1 && par2) return par1;
else return new Point2D(-1.0F, -1.0F);
}
Выражение вызова операторной функции “дизъюнкция” имеет вид:
if (p0 | p1) Console.WriteLine(“true!”);
А как же || и &&
Эти операции сводятся к ранее объявленным операторным функциям.
Обозначим символом T тип, в котором была объявлена данная операторная функция.
Если при этом операнды операций && или || являются операндами типа T, и для них были объявлены соответствующие операторные функции operator &() и/или operator |(), то для успешной эмуляции операций && или || должны выполняться следующие уусловия:
Тип возвращаемого значения и типы каждого из параметров данной операторной функции должны быть типа T. Операторные функции operator & и operator |, определённые на множестве операндов типа T, должны возвращать результирующее значение типа T.
К результирующему значению применяется объявленная в классе T операторная функция operator true (operator false).
При этом приобретают смысл операции && или ||. Их значение вычисляется в результате комбинации операторных функций operator true() или operator false() со следующими операторными функциями:
x && y представляется в виде выражения, построенного на основе трёхместной операции
T.false(x)? x: T.&(x, y),
где T.false(x) является выражением вызова объявленной в классе операторной функции false, а T.&(x, y) – выражением вызова объявленной в классе T операторной функции &.
Таким образом, сначала определяется “истинность” операнда x, и если значением соответствующей операторной функции является ложь, результатом операции оказывается значение, вычисленное для x. В противном случае определяется “истинность” операнда y, и результирующее значение определяется как КОНЪЮНКЦИЯ истинностных значений операндов x и y.
x || y представляется в виде выражения, построенного на основе трёхместной операции
T.true(x)? x: T.|(x, y),
где T.true(x) является выражением вызова объявленной в классе операторной функции, а T.|(x, y) – выражением вызова объявленной в классе T операторной функции |.
Таким образом, сначала определяется “истинность” операнда x, и если значением соответствующей операторной функции является истина, результатом операции оказывается значение, вычисленное для x. В противном случае определяется “истинность” операнда y, и результирующее значение определяется как ДИЗЪЮНКЦИЯ истинностных значений операндов x и y.
При этом в обоих случаях “истинностное” значение x вычисляется один раз, значение выражения, представленного операндом y не вычисляется вообще, либо определяется один раз.
И вот результат…
using System;
namespace ThisInConstruct
{
class Point2D
{
private float x, y;
public float X
{
get
{
return x;
}
}
public float PropertyY
{
get
{
return y;
}
set
{
string ans = null;
Console.Write("Are You sure to change the y value of object of Point2D? (y/n) >> ");
ans = Console.ReadLine();
if (ans.Equals("Y") || ans.Equals("y"))
{
y = value;
Console.WriteLine("The value y of object of Point2D changed...");
}
}
}
public Point2D(float xKey, float yKey)
{
Console.WriteLine("Point2D({0}, {1}) is here!", xKey, yKey);
// Какой - нибудь сложный обязательный
// код инициализации данных-членов класса.
int i = 0;
while (i < 100)
{
x = xKey;
y = yKey;
i++;
}
}
// А все другие конструкторы в обязательном порядке предполагают
// регламентные работы по инициализации значений объекта - и делают при этом
// ещё много чего...
public Point2D():this(0,0)
{
int i;
for (i = 0; i < 100; i++)
{
// Хорошо, что значения уже проинициализированы!
// Здесь своих проблем хватает.
}
Console.WriteLine("Point2D() is here!");
}
public Point2D(Point2D pKey):this(pKey.x, pKey.y)
{
int i;
for (i = 0; i < 100; i++)
{
// Хорошо, что значения уже проинициализированы!
// Здесь своих проблем хватает.
}
Console.WriteLine("Point2D({0}) is here!", pKey.ToString());
}
// Перегруженные операции обязаны возвращать значения!
// Операторные функции! Must be declared static and public.
// Префиксная и постфиксная формы ++ и -— не различаются по результату выполнения
// (что есть криво)! Тем не менее, они здесь реализуются:
// одна как префиксная…
public static Point2D operator ++ (Point2D par)
{
par.x++;
par.y++;
return par;
}
// другая как постфиксная…
public static Point2D operator -- (Point2D par)
{
Point2D tmp = new Point2D(par);
par.x--;
par.y--;
return tmp;
}
// Бинарные операции также обязаны возвращать значения!
public static Point2D operator + (Point2D par1, Point2D par2)
{
return new Point2D(par1.x+par2.x,par1.y+par2.y);
}
// От перемены мест слагаемых сумма ... :
// Point2D + float
public static Point2D operator + (Point2D par1, float val)
{
return new Point2D(par1.x+val,par1.y+val);
}
// float + Point2D
public static Point2D operator + (float val, Point2D par1)
{
return new Point2D(val+par1.x,val+par1.y);
}
// Перегрузка булевских операторов. Это ПАРНЫЕ операторы.
// Объекты типа Point2D приобретают способность судить об истине и лжи!
// А что есть истина? Критерии ИСТИННОСТИ (не путать с истиной)
// могут быть самые разные.
public static bool operator true (Point2D par)
{
if (par.x == 1.0F && par.y == 1.0F) return true;
else return false;
}
public static bool operator false (Point2D par)
{
if (par.x == 0.0F && par.y == 0.0F) return false;
else return true;
}
//========================================================================
public static Point2D operator | (Point2D par1, Point2D par2)
{
if (par1) return par1;
if (par2) return par2;
else return new Point2D(-1.0F, -1.0F);
}
public static Point2D operator & (Point2D par1, Point2D par2)
{
if (par1 && par2) return par1;
else return new Point2D(-1.0F, -1.0F);
}
}
/// <summary>
/// Стартовый класс.
/// </summary>
class C1
{
static void Main(string[] args)
{
Console.WriteLine("__________");
Point2D p0 = new Point2D();
Console.WriteLine("__________");
Point2D p1 = new Point2D(GetVal(), GetVal());
Console.WriteLine("__________");
Point2D p2 = new Point2D(p1);
Console.WriteLine("__________");
// Меняем значение y объекта p1...
Console.WriteLine("**********");
p1.PropertyY = GetVal();
Console.WriteLine("**********");
Console.WriteLine("p0.x == {0}, p0.y == {1}", p0.X,p0.PropertyY);
Console.WriteLine("p1.x == {0}, p1.y == {1}", p1.X,p1.PropertyY);
Console.WriteLine("p2.x == {0}, p2.y == {1}", p2.X,p2.PropertyY);
Console.WriteLine("##########");
p0++;
++p1;
// После объявления операторных функций true и false объекты класса Point2D
// могут могут включаться в контекст условного оператора и оператора цикла.
if (p1) Console.WriteLine("true!");
else Console.WriteLine("false!");
// Конъюнкции и дизъюнкции. Выбирается объект p0 или p1,
// для которого вычисляется истинностное значение.
if (p0 | p1) Console.WriteLine("true!");
if (p0 & p1) Console.WriteLine("true!");
if (p0 || p1) Console.WriteLine("true!");
if (p0 && p1) Console.WriteLine("true!");
for ( ; p2; p2++)
{
Console.WriteLine("p2.x == {0}, p2.y == {1}", p2.X,p2.PropertyY);
}
Console.WriteLine("p0.x == {0}, p0.y == {1}", p0.X,p0.PropertyY);
Console.WriteLine("p1.x == {0}, p1.y == {1}", p1.X,p1.PropertyY);
Console.WriteLine("p2.x == {0}, p2.y == {1}", p2.X,p2.PropertyY);
}
public static float GetVal()
{
float fVal;
string str = null;
while (true)
{
try
{
Console.Write("float value, please >> ");
str = Console.ReadLine();
fVal = float.Parse(str);
return fVal;
}
catch
{
Console.WriteLine("This is not a float value...");
}
}
}
}
}