1   2   3   4   5   6
Ім'я файлу: конспект №1.docx
Розширення: docx
Розмір: 71кб.
Дата: 14.11.2021
скачати


Как и во многих языках программирования, в C# есть своя система типов данных, которая используется для создания переменных. Тип данных определяет внутреннее представление данных, множество значений, которые может принимать объект, а также допустимые действия, которые можно применять над объектом.

В языке C# есть следующие примитивные типы данных:

  • bool: хранит значение true или false (логические литералы). Представлен системным типом System.Boolean

    1

    2

    bool alive = true;

    bool isDead = false;

  • byte: хранит целое число от 0 до 255 и занимает 1 байт. Представлен системным типом System.Byte

    1

    2

    byte bit1 = 1;

    byte bit2 = 102;

  • sbyte: хранит целое число от -128 до 127 и занимает 1 байт. Представлен системным типом System.SByte

    1

    2

    sbyte bit1 = -101;

    sbyte bit2 = 102;

  • short: хранит целое число от -32768 до 32767 и занимает 2 байта. Представлен системным типом System.Int16

    1

    2

    short n1 = 1;

    short n2 = 102;

  • ushort: хранит целое число от 0 до 65535 и занимает 2 байта. Представлен системным типом System.UInt16

    1

    2

    ushort n1 = 1;

    ushort n2 = 102;

  • int: хранит целое число от -2147483648 до 2147483647 и занимает 4 байта. Представлен системным типом System.Int32. Все целочисленные литералы по умолчанию представляют значения типа int:

    1

    2

    3

    int a = 10;

    int b = 0b101;  // бинарная форма b =5

    int c = 0xFF;   // шестнадцатеричная форма c = 255

  • uint: хранит целое число от 0 до 4294967295 и занимает 4 байта. Представлен системным типом System.UInt32

    1

    2

    3

    uint a = 10;

    uint b = 0b101;

    uint c = 0xFF;

  • long: хранит целое число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 и занимает 8 байт. Представлен системным типом System.Int64

    1

    2

    3

    long a = -10;

    long b = 0b101;

    long c = 0xFF;

  • ulong: хранит целое число от 0 до 18 446 744 073 709 551 615 и занимает 8 байт. Представлен системным типом System.UInt64

    1

    2

    3

    ulong a = 10;

    ulong b = 0b101;

    ulong c = 0xFF;

  • float: хранит число с плавающей точкой от -3.4*1038 до 3.4*1038 и занимает 4 байта. Представлен системным типом System.Single

  • double: хранит число с плавающей точкой от ±5.0*10-324 до ±1.7*10308 и занимает 8 байта. Представлен системным типом System.Double

  • decimal: хранит десятичное дробное число. Если употребляется без десятичной запятой, имеет значение от ±1.0*10-28 до ±7.9228*1028, может хранить 28 знаков после запятой и занимает 16 байт. Представлен системным типом System.Decimal

  • char: хранит одиночный символ в кодировке Unicode и занимает 2 байта. Представлен системным типом System.Char. Этому типу соответствуют символьные литералы:

    1

    2

    3

    char a = 'A';

    char b = '\x5A';

    char c = '\u0420';

  • string: хранит набор символов Unicode. Представлен системным типом System.String. Этому типу соответствуют строковые литералы.

    1

    2

    string hello = "Hello";

    string word = "world";

  • object: может хранить значение любого типа данных и занимает 4 байта на 32-разрядной платформе и 8 байт на 64-разрядной платформе. Представлен системным типом System.Object, который является базовым для всех других типов и классов .NET.

1

2

3

object a = 22;

object b = 3.14;

object c = "hello code";

Например, определим несколько переменных разных типов и выведем их значения на консоль:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

using System;

 

namespace HelloApp

{

    class Program

    {

        static void Main(string[] args)

        {

            string name = "Tom";

            int age = 33;

            bool isEmployed = false;

            double weight = 78.65;

             

            Console.WriteLine($"Имя: {name}");

            Console.WriteLine($"Возраст: {age}");

            Console.WriteLine($"Вес: {weight}");

            Console.WriteLine($"Работает: {isEmployed}");

        }

    }

}

Для вывода данных на консоль здесь применяется интерполяция: перед строкой ставится знак $ и после этого мы можем вводить в строку в фигурных скобках значения переменных. Консольный вывод программы:

Имя: Tom

Возраст: 33

Вес: 78,65

Работает: False

Использование суффиксов


При присвоении значений надо иметь в виду следующую тонкость: все вещественные литералы рассматриваются как значения типа double. И чтобы указать, что дробное число представляет тип float или тип decimal, необходимо к литералу добавлять суффикс: F/f - для float и M/m - для decimal.

1

2

3

4

5

float a = 3.14F;

float b = 30.6f;

 

decimal c = 1005.8M;

decimal d = 334.8m;

Подобным образом все целочисленные литералы рассматриваются как значения типа int. Чтобы явным образом указать, что целочисленный литерал представляет значение типа uint, надо использовать суффикс U/u, для типа long - суффикс L/l, а для типа ulong - суффикс UL/ul:

1

2

3

uint a = 10U;

long b = 20L;

ulong c = 30UL;

Использование системных типов


Выше при перечислении всех базовых типов данных для каждого упоминался системный тип. Потому что название встроенного типа по сути представляет собой сокращенное обозначение системного типа. Например, следующие переменные будут эквивалентны по типу:

1

2

int a = 4;

System.Int32 b = 4;

Неявная типизация


Ранее мы явным образом указывали тип переменных, например, int x;. И компилятор при запуске уже знал, что x хранит целочисленное значение.

Однако мы можем использовать и модель неявной типизации:

1

2

3

4

5

var hello = "Hell to World";

var c = 20;

             

Console.WriteLine(c.GetType().ToString());

Console.WriteLine(hello.GetType().ToString());

Для неявной типизации вместо названия типа данных используется ключевое слово var. Затем уже при компиляции компилятор сам выводит тип данных исходя из присвоенного значения. В примере выше использовалось выражение Console.WriteLine(c.GetType().ToString());, которое позволяет нам узнать выведенный тип переменной с. Так как по умолчанию все целочисленные значения рассматриваются как значения типа int, то поэтому в итоге переменная c будет иметь тип int или System.Int32

Эти переменные подобны обычным, однако они имеют некоторые ограничения.

Во-первых, мы не можем сначала объявить неявно типизируемую переменную, а затем инициализировать:

1

2

3

4

5

6

7

// этот код работает

int a;

a = 20;

 

// этот код не работает

var c;

c= 20;

Во-вторых, мы не можем указать в качестве значения неявно типизируемой переменной null:

1

2

// этот код не работает

var c=null;

Так как значение null, то компилятор не сможет вывести тип данных.

double или decimal


Из выше перечисленного списка типов данных очевидно, что если мы хотим использовать в программе числа до 256, то для их хранения мы можем использоват переменные типа byte. При использовании больших значений мы можем взять тип short, int, long. То же самое для дробных чисел - для обычных дробных чисел можно взять тип float, для очень больших дробных чисел - тип double. Тип decimal здесь стоит особняком в том плане, что несмотря на большую разрядность по сравнению с типом double, тип double может хранить большее значение. Однако значение decimal может содержать до 28 знаков после запятой, тогда как значение типа double - 15-16 знаков после запятой.

Decimal чаще находит применение в финансовых вычислениях, тогда как double - в математических операциях. Общие различия между этими двумя типами можно выразить следующей таблицей:




Decimal

Double

Наибольшее значение

1028

10308

Наименьшее значение (без учета нуля)

10-28

10-323

Знаков после запятой

28

15-16

Разрядность

16 байт

8 байт

Операций в секунду

сотни миллионов

миллиарды


Поскольку код C# является статически типизированным во время компиляции, после объявления переменной ее нельзя объявить повторно или назначить ей значения другого типа, если этот тип невозможно неявно преобразовать в тип переменной. Например, string невозможно неявно преобразовать в int. Поэтому после объявления i как int нельзя назначить ей строку "Hello", как показано в следующем коде:

C#Копировать

int i;
// error CS0029: Cannot implicitly convert type 'string' to 'int'

i = "Hello";

Тем не менее иногда может потребоваться скопировать значение в переменную или параметр метода другого типа. Например, может потребоваться передать целочисленную переменную в метод, параметр которого имеет тип double. Или может понадобиться присвоить переменную класса переменной типа интерфейса. Такого рода операции называются преобразованиями типа. В C# можно выполнять следующие виды преобразований.

  • Неявные преобразования. Специальный синтаксис не требуется, так как преобразование всегда завершается успешно и данные не будут потеряны. Примеры включают преобразования из меньших в большие целочисленные типы и преобразования из производных классов в базовые классы.

  • Явные преобразования (приведения) . Для явных преобразований требуется выражение приведения. Приведение требуется, если в ходе преобразования данные могут быть утрачены или преобразование может завершиться сбоем по другим причинам. Типичными примерами являются числовое преобразование в тип с меньшей точностью или меньшим диапазоном и преобразование экземпляра базового класса в производный класс.

  • Пользовательские преобразования. Такие преобразования выполняются специальными методами, которые можно определить для включения явных и неявных преобразований между пользовательскими типами без связи "базовый класс — производный класс". Дополнительные сведения см. в разделе Операторы пользовательского преобразования.

  • Преобразования с использованием вспомогательных классов. Чтобы выполнить преобразование между несовместимыми типами, например целыми числами и объектами System.DateTime или шестнадцатеричными строками и массивами байтов, можно использовать классы System.BitConverter и System.Convert, а также методы Parse встроенных числовых типов, такие как Int32.Parse. Дополнительные сведения см. в руководствах по преобразованию массива байтов в значение типа intпреобразованию строки в число и преобразованию из шестнадцатеричных строк в числовые типы.

Неявные преобразования

Для встроенных числовых типов неявное преобразование можно выполнить, если сохраняемое значение может уместиться в переменной без усечения или округления. При использовании целочисленных типов это означает, что диапазон исходного типа является надлежащим подмножеством диапазона для целевого типа. Например, переменная типа long (64-разрядное целое число) может хранить любое значение, которое может хранить переменная int (32-разрядное целое число). В следующем примере компилятор неявно преобразует значение num справа в тип long перед назначением bigNum.

C#Копировать

// Implicit conversion. A long can

// hold any value an int can hold, and more!

int num = 2147483647;

long bigNum = num;

Полный список всех неявных числовых преобразований см. в разделе Таблица неявных числовых преобразований в статье Встроенные числовые преобразования.

Для ссылочных типов неявное преобразование всегда предусмотрено из класса в любой из его прямых или косвенных базовых классов или интерфейсов. Никакой специальный синтаксис не требуется, поскольку производный класс всегда содержит все члены базового класса.

C#Копировать

Derived d = new Derived();
// Always OK.

Base b = d;

Явные преобразования

Тем не менее если преобразование нельзя выполнить без риска потери данных, компилятор требует выполнения явного преобразования, которое называется приведением. Приведение — это способ явно указать компилятору, что необходимо выполнить преобразование и что вам известно, что может произойти потеря данных или приведение может завершиться сбоем во время выполнения. Чтобы выполнить приведение, укажите тип, в который производится приведение, в круглых скобках перед преобразуемым значением или переменной. В следующей программе выполняется приведение типа double в int. Программа не будет компилироваться без приведения.

C#Копировать

class Test

{

static void Main()

{

double x = 1234.7;

int a;

// Cast double to int.

a = (int)x;

System.Console.WriteLine(a);

}

}

// Output: 1234

Полный список всех поддерживаемых явных числовых преобразований см. в разделе Таблица явных числовых преобразований в статье Встроенные числовые преобразования.

Для ссылочных типов явное приведение является обязательным, если необходимо преобразовать базовый тип в производный тип:

C#Копировать

// Create a new derived type.

Giraffe g = new Giraffe();
// Implicit conversion to base type is safe.

Animal a = g;
// Explicit conversion is required to cast back

// to derived type. Note: This will compile but will

// throw an exception at run time if the right-side

// object is not in fact a Giraffe.

Giraffe g2 = (Giraffe)a;

Операция приведения между ссылочными типами не меняет тип времени выполнения базового объекта; изменяется только тип значения, который используется в качестве ссылки на этот объект. Дополнительные сведения см. в разделе Полиморфизм.

Исключения преобразования типов во время выполнения

В некоторых преобразованиях ссылочных типов компилятор не может определить, будет ли приведение допустимым. Есть вероятность, что правильно скомпилированная операция приведения завершится сбоем во время выполнения. Как показано в следующем примере, приведение типа, завершившееся сбоем во время выполнения, вызывает исключение InvalidCastException.

C#Копировать

class Animal

{

public void Eat() => System.Console.WriteLine("Eating.");
public override string ToString() => "I am an animal.";

}
class Reptile : Animal { }

class Mammal : Animal { }
class UnSafeCast

{

static void Main()

{

Test(new Mammal());
// Keep the console window open in debug mode.

System.Console.WriteLine("Press any key to exit.");

System.Console.ReadKey();

}
static void Test(Animal a)

{

// System.InvalidCastException at run time

// Unable to cast object of type 'Mammal' to type 'Reptile'

Reptile r = (Reptile)a;

}

}

Метод Test имеет параметр Animal, поэтому явное приведение a аргумента к Reptile формирует опасное допущение. Более безопасно будет не делать допущений, а проверить тип. C# предоставляет оператор is, чтобы можно было проверить совместимость перед фактическим выполнением приведения. Дополнительные сведения см. в статье Практическое руководство. Безопасное приведение с помощью сопоставления шаблонов, а также операторов is и as.
Рядок – це об’єкт типу string(System.String в нотації .Net), який зберігає в собі текстовий рядок. Хоча рядки відносять до примітивних типів даних, насправді вони мають тип за посиланням. Всередині рядків зберігається колекція символів типу char.

Рядок є незмінним об’єктом, це означає, що після створення його не можна змінити, а будь які зміни, до прикладу об’єднання, призводять до створення нового рядку.

Оскільки рядкові змінні дуже часто використовуються в програмування, мова C# містить велику кількість операцій для роботи з рядками.

C# дозволяє читати окремі символи рядка, звертаючись до окремого символу по індексу, при цьому редагування не дозволяється:

var s = "Текст";

for (int i = 0; i < s.Length; i++)

{

Console.WriteLine(s[i]);

}
s[0] = "т"; // помилка, змінити символ в рядку не дозволяється

  1   2   3   4   5   6

скачати

© Усі права захищені
написати до нас