- •Тема 2.1.1 Синтаксис языка c#. Данные и операции над ними
- •Тема 2.1.1 Синтаксис языка c#. Данные и операции над ними 1
- •Какие типы данных присутствуют в c#?
- •Int[] mass;// объявление массива целых чисел mass
- •Какие типы данных встроены в c#?
- •Почему в c# типы данных являются одновременно и классами?
- •При каких условиях переменным одного типа можно присваивать значения другого типа?
- •Как в c# автоматизируется преобразование типов?
- •Как в c# объявляются и инициируются переменные?
- •Где в c# объявляются переменные?
- •Каково поведение локальных переменных в c#?
- •Как в c# объявляются константы?
- •Какие математические функции и константы встроены в c#?
- •Как в c# генерировать случайные числа?
- •Выводы:
Почему в c# типы данных являются одновременно и классами?
В C# все типы – встроенные и пользовательские - одновременно являются классами, связанными отношением наследования.
Родительским, базовым классом является класс Object. Все остальные типы или, точнее, классы являются его потомками, наследуя методы этого класса.
У класса Object есть четыре наследуемых метода:
1. bool Equals(object obj) - проверяет эквивалентность текущего объекта и объекта, переданного в качестве аргумента;
2. System.Type GetType() - возвращает системный тип текущего объекта;
3. string ToString() - возвращает строку, связанную с объектом. Для арифметических типов возвращается значение, преобразованное в строку;
4. int GetHashCode() - служит как хэш-функция в соответствующих алгоритмах поиска по ключу при хранении данных в хэш-таблицах.
Примеры объявления переменных и присваивания им значений:
int x=11; // как значимый тип
int v = new Int32(); // как объект, значение 0 - по умолчанию
v = 007; // как значимый тип, присваивается значение 7
string s1 = "Agent";// как объект, ссылка на константную строку "Agent" в памяти
s1 = s1 + v.ToString() +x.ToString();// v и x как объекты
При каких условиях переменным одного типа можно присваивать значения другого типа?
Чтобы присваивание было допустимым, типы должны быть согласованными.
Для оператора X=Y; где X типа TX, а Y типа TY присваивание допустимо, если:
- либо в классе TY или его предке определена функция преобразования в тип TX;
- либо класс TY является потомком класса TX, но не наоборот.
Первое условие характерно для большинства встроенных типов. Например, целые числа преобразуются в действительные и даже в строковые.
Второе условие характерно для классов, создаваемых пользователем, и для класса Object. Его переменным можно присваивать значения любых типов, так как это предок всех классов. После такого присваивания переменная класса Object приобретает текущий тип в соответствии с типом присвоенного значения.
Заметим, что в C# нельзя перегружать оператор присваивания.
Функция преобразования в тип TX из типа TY может быть определена только в том случае, если TX и TY не связаны отношением наследования.
ВОПРОС К АУДИТОРИИ
Почему нельзя переменной – потомку присвоить значение переменной – родителя?
Почему можно делать наоборот?
Заметим, что если TX и TY классы, согласованные по присваиванию, то оператор X=Y; просто переставляет ссылку X на область памяти, занимаемую переменной Y. Так что «лишние» поля хоть и не используются предком, но и не исчезают из памяти. Их можно «вернуть обратно» с помощью явного преобразования типа. Например, допустим оператор Y =(TY)X;
Поле a
Поле b
Поле c
Поле d
Что из этого следует?
- Переменные класса Object можно использовать для временного хранения любых значений, которые можно извлекать из них с помощью явного преобразования типа.
- В C# при присваивании переменных типа массив, строка и класс друг другу следует быть особо внимательным, так как при присваивании значения полей не копируются, а становятся общими.
Совет Как скопировать элементы массива m2 в массив m1
m2.CopyTo(m1,n); //Переписывает все элементы из m2 в m1, начиная с позиции n в m1. // Чтобы это работало, в m1 должно быть достаточно места.
Для многомерных массивов можно воспользоваться статическим методом Copy(m2,m1) класса Array.
Совет Как скопировать строку s2 в строку s1
В C# это невозможно выполнить в цикле, посимвольно, так как элементы строки доступны только для чтения. Нужно создать новую строку на основе имеющейся строки или ее части:
s1 = String.Copy(s2); //Создает копию s2 и присваивает ее адрес s1
s1 = s2.Substring(2,5); //Создает копию подстроки s2 и присваивает ее адрес s1
Совет Как скопировать объект в объект
Если копируются экземпляры одного класса или связанные наследованием, то оператор присваивания переустанавливает ссылку. Поэтому придется в этом классе запрограммировать функцию (например, свойство с именем Val). Эта функция должна создать новый объект, переписать в него все требуемые поля и вернуть ссылку на него.
Если копируются экземпляры различных классов, не связанных наследованием, то оператор присваивания вызывает функцию преобразования типа, определенную в классе присваиваемого типа.
Функция преобразования из типа TY в тип TX может быть определена только в том случае, если TX и TY не связаны отношением наследования. Она задается в классе TY следующим образом: public static implicit operator TX(TY y) { return …; }