Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 11 лет назад пользователемВладимир Наровчатов
1 Система типов Значение выражения характеризуется типом. При разработке кода любой сложности знание правил кодирования, вычисления и преобразования значений различных типов является условием создания правильно выполняемой программы. Типы-значения - сохраняют свое фактическое значение в стеке. Типы-ссылки хранят в стеке лишь адрес объекта, а сам объект сохраняется в куче. Все ссылочные объекты создаются операцией new
2 .NET Framework Class Library Используемые в.NET языки программирования основываются на общей системе типов. Между именами простых типов в C# и именами типов, объявленных в Framework Class Library, существует взаимно однозначное соответствие. CLS В разных языках типам, удовлетворяющим CLS-спецификации, будут соответствовать одни и те же элементарные типы. Характеристики встроенных (простых) типов отражены в следующей таблице:
3 Логический тип Имя типаСистемный типЗначенияРазмер bool System.Booleantrue, false8 бит Арифметические целочисленные типы Имя типаСистемный типДиапазонРазмер sbyte System.SByte Знаковое, 8 Бит byte System.Byte0 255Беззнаковое, 8 Бит short System.Short Знаковое, 16 Бит ushort System.UShort Беззнаковое, 16 Бит int System.Int32(-2*10 9 2*10 9 )Знаковое, 32 Бит uint System.UInt32(0 4*10 9 )Беззнаковое, 32 Бит long System.Int64(-9* *10 18 )Знаковое, 64 Бит ulong System.UInt64(0 18*10 18 )Беззнаковое, 64 Бит Арифметический тип с плавающей точкой Имя типаСистемный типДиапазонТочность float System.Single+1.5* * цифр double System.Double+5.0* * цифр Арифметический тип с фиксированной точкой decimal System.Decimal+1.0* * значащих цифр Символьные типы char System.CharU U+ffff16 бит Unicode символ string System.StringСтрока из символов Unicode Объектный тип Имя типаСистемный типПримечание object System.ObjectПрародитель всех встроенных и пользовательских типов
4 Объявление и инициализация Система встроенных типов C# основывается на системе типов.NET Framework Class Library. При создании IL-кода компилятор осуществляет их отображение в типы из.NET FCL. Эквивалентные формы записи операторов определения переменных элементарных типов значений: int a; System.Int32 a; Эквивалентные формы записи операторов определения и инициализации переменных типа значения: int a = 0; int a = new int( ); System.Int32 a = 0; System.Int32 a = new System.Int32();
5 CLR неинициализированных локальных переменных Здесь следует учитывать важное обстоятельство: CLR не допускает использования в выражениях неинициализированных локальных переменных. В C# к таковым относятся переменные, объявленные в теле метода. Так что при разработке алгоритма следует обращать на это особое внимание. int a; // Объявление a int b; // Объявление b b = 10; // Инициализация b a = b+b; // Инициализация a
6 Для отображения фактического типа для любого типа C# используется системный метод GetType( ) class Program { static void Main(string[] args) { int a = 10; Console.WriteLine(a.GetType()); Console.ReadLine(); } Также можно использовать и оператор typeof System.Type type = a.GetType(); Console.WriteLine(type);
7 наследует класс В C# объявление любой структуры и класса основывается на объявлении предопределенного класса object (наследует класс object)
8 Важно понимать две фундаментальных тезиса о системе типов в.NET Framework: System.Int32 System.Object Поддерживается принцип наследования. Типы могут быть производными от других типов, которые называются базовыми типами. Производный тип наследует (с некоторыми ограничениями) методы, свойства и другие члены базового типа. Базовый тип, в свою очередь, может быть производным от какого-то другого типа, при этом производный тип наследует члены обоих базовых типов в иерархии наследования. Все типы, включая встроенные числовые типы, например, System.Int32, в конечном счете являются производными от одного базового типа, который является System.Object. Эта унифицированная иерархия типов называется Система общих типов CTS (CTS). тип значенияссылочный тип Каждый тип в CTS определен либо как тип значения, либо как ссылочный тип. Типы, определяемые с помощью ключевого слова struct, являются типами значений; все встроенные числовые типы являются struct. Типы, определяемые с помощью ключевого слова class, являются ссылочными типами. Правила времени компиляции и поведение времени выполнения ссылочных типов отличается от правил времени компиляции и поведения времени выполнения типов значений.
9 как обычные классы В отличие от С++ в C# переменных элементарных типов реализованы как обычные классы Следствием этого является возможность вызова от имени объектов представителей любой структуры или класса методов, унаследованных от класса object Типы значений являются производными от System.ValueType, являющегося производным от System.Object. Типы, производные от System.ValueType, имеют особое поведение в среде CLR.
10 Переменные типа значения напрямую содержат их значения. Не существует отдельного размещения кучи или служебных данных сборки мусора для переменных типа значения. Типы значений являются запечатанными, что означает, например, что нельзя произвести тип от System.Int32
11 Ключевое слово struct используется для создания собственных пользовательских типов значений. Обычно структура используется как контейнер для небольшого набора связанных переменных, как показано в следующем примере: public struct CoOrds { public int x, y; public CoOrds(int p1, int p2) { x = p1; y = p2; }
12 Другой категорией типов значений является перечисление. Перечисление определяет набор именованных интегральных констант. Например, перечисление System.IO.FileMode в библиотеке классов платформы.NET Framework содержит набор именованных констант целого типа, которые задают, как должен быть открыт файл. Это определено, как показано в следующем примере: public enum FileMode { CreateNew = 1, Create = 2, Open = 3, OpenOrCreate = 4, Truncate = 5, Append = 6, } Все перечисления наследуются от System.Enum, который наследуется от System.ValueType.
13 Nullable типы Тип, допускающие значения NULL, являются экземплярами структуры System.Nullable. Тип, допускающий значения NULL, может представлять правильный диапазон значений для своего базового типа значений и дополнительное пустое значение null. Например, для Nullable, называемого "тип Int32, допускающий значения NULL, можно назначить любое значение от до или значение null.
14 Для Nullable можно назначить значения true, false или null. Возможность назначения значения null для числовых и логических типов особенно полезна при работе с базами данных и другими типами данных, содержащих элементы, которым может быть не назначено значение. Например, логическое поле в базе данных может хранить значения true или false или может быть не задано Допускающие значение NULL типы объявляются одним из следующих способов: T является базовым типом для типа, допускающего значение null. T может быть любым типом значения, включая struct; он не может быть ссылочным типом. System.Nullable variable -или краткая форма- T? variable int? i = 10; double? d1 = 3.14; bool? flag = null; char? letter = 'a'; I nt?[] arr = new int?[10];
15 Каждый экземпляр допускающего значение NULL типа имеет два общих предназначенных только для чтения свойства: HasValue Свойство HasValue имеет тип bool. Это свойство имеет значение true, если переменная содержит определенное значение. Value Свойство Value имеет тот же тип, что и у базового типа. Если свойство HasValue имеет значение true, то свойство Value содержит имеющее смысл значение. Если свойство HasValue имеет значение false, то доступ к свойству Value будет приводить к формированию ошибки InvalidOperationException. В этом примере член HasValue используется для выполнения проверки, содержит ли переменная какое-либо значение, прежде чем пытаться его показать: int? x = 10; if (x.HasValue) { System.Console.WriteLine(x.Value); } еlse { System.Console.WriteLine("Undefined"); } int? y = 10; if (y != null) { System.Console.WriteLine(y.Value); } else { System.Console.WriteLine("Undefined"); }
16 NULL тип может быть приведен к обычному типу либо явным образом с помощью приведения, либо с помощью свойства Value. Например: int? n = null; //int m1 = n; // Will not compile. int m2 = (int)n; // Compiles, but will create an exception if n is null. int m3 = n.Value; // Compiles, but will create an exception if n is null. Преобразование из обычного типа в допускающий значение NULL тип является неявным: int? n2; n2 = 10; // Implicit conversion. int? n1 = null; Переменной допускающего значение NULL типа может быть присвоено значение NULL с помощью ключевого слова null, как показано в следующем примере:
17 Характеристики класса object предопределенныепользовательскиессылочные типытипы значений Все типы, предопределенные и пользовательские, ссылочные типы и типы значений, наследуют непосредственно или косвенно от object. Переменным типа object можно назначать значения любых типов. class ObjectTest { public int i = 10; } class MainClass2 { static void Main() { object a; a = 1; // an example of boxing Console.WriteLine(a); Console.WriteLine(a.GetType()); Console.WriteLine(a.ToString()); a = new ObjectTest(); ObjectTest classRef; classRef = (ObjectTest)a; Console.WriteLine(classRef.i); } /* Output 1 System.Int */
18 упаковывается Когда переменная типа значения преобразуется в объект, говорят, что она упаковывается (boxing). short s = 25; object objShort = s; распаковывается Когда переменная типа object преобразуется в тип значения, говорят, что она распаковывается (unboxing). short anyShort = (short) objShort;
19 .NET Framework Object Так как все классы в платформе.NET Framework являются производными класса Object, все методы, определённые в классе Object, доступны для всех объектов в системе. В производных классах могут переопределяться (и переопределяются) некоторые из этих методов, включая перечисленные ниже: Equals поддерживает сравнение объектов. GetType () - возвращает системный тип объекта; GetHashCode создаёт число, соответствующее значению объекта, обеспечивающее возможность использования хэш-таблицы. ToString создаёт понятную для пользователя строку текста, в которой описывается экземпляр класса.
20 class Program { int x = 11; uint ux = 1111; float y = 5.5f; double dy = 5.55; string s = "Hello!"; object obj = new Object(); void WhoIsWho(string name, object any) { Console.WriteLine("type {0} is {1}, value is {2}", name, any.GetType(), any.ToString()); } public void test() { WhoIsWho("x",x); WhoIsWho("ux",ux); WhoIsWho("y",y); WhoIsWho("dy",dy); WhoIsWho("s",s); WhoIsWho(" f", f); obj = f; WhoIsWho("obj",obj); } static void Main(string[] args) { Program o1 = new Program(); o1.test(); }
21 Преобразование встроенных типов Неявные преобразования: Нередко значения переменных одного типа присваиваются переменным другого типа. совместимые Если в одной операции присваивания смешиваются совместимые типы данных, то значение в правой части оператора присваивания автоматически преобразуется в тип, указанный в левой его части. int i; float f; i = 10; f = i; // присвоить целое значение переменной типа float Но вследствие строгого контроля типов далеко не все типы данных в С# оказываются полностью совместимыми, а следовательно, не все преобразования типов разрешены в неявном виде. Например, типы bool и int несовместимы.
22 Когда данные одного типа присваиваются переменной другого типа, неявное преобразование типов происходит автоматически при следующих условиях: оба типа совместимы диапазон представления чисел целевого типа шире, чем у исходного типа Преобразования, при которых возможна потеря данных необходимо осуществлять явно Но при этом часть информации может быть потеряна. Для создания приложений, в которых потеря данных должна быть недопустимой, в С# предлагаются такие ключевые слова, как checked и unchecked, которые позволяют гарантировать, что потеря данных не окажется незамеченной. short х; int у = 5; х = у; //ошибка х = (short) у; //OK
23 Если оператор (или блок операторов) заключен в контекст checked, компилятор С# генерирует дополнительные CIL-инструкции, обеспечивающие проверку. В случае возникновения условия переполнения во время выполнения будет генерироваться исключение System.OverflowException. namespace ConsoleApplication1 { class Program { static void Main(string[] args) { byte var1 = 250; byte var2 = 150; try { byte sum = checked((byte)(var1+var2)); Console.WriteLine("Сумма: {0}", sum); } catch (OverflowException ex) { Console.WriteLine(ex.Message); Console.ReadLine(); }
24 Конструкции управления контролем за переполнением имеют две формы: операторную, которая обеспечивает контроль над выполнением одного выражения: ::::: short x = 32767; short y = 32767; short z = 0; try { z = checked(x + unchecked(x+y)); } catch (System.OverflowException e) { Console.Writeline("Переполнение при выполнении сложения"); } return z; ::::: При этом контролируемое выражение может быть произвольной формы и сложности и может содержать другие вхождения как контролируемых, так и неконтролируемых выражений;
25 блочную, которая обеспечивает контроль над выполнением операций в блоке операторов: ::::: short x = 32767; short y = 32767; short z = 0, w = 0; try { unchecked { w = x+y; } checked { z = x+w; } catch (System.OverflowException e) { Console.Writeline("Переполнение при выполнении сложения"); } return z; :::::
26 Если создается приложение, в котором переполнение никогда не должно проходить незаметно, может выясниться, что обрамлять ключевым словом checked приходится раздражающе много строк кода. На такой случай в качестве альтернативного варианта в компиляторе С# поддерживается флаг /checked. При активизации этого флага проверке на предмет возможного переполнения будут автоматически подвергаться все имеющиеся в коде арифметические операции, без применения для каждой из них ключевого слова checked. Обнаружение переполнения точно так же приводит к генерации соответствующего исключения во время выполнения. В С# предусмотрено ключевое слово unchecked, которое позволяет отключить выдачу связанного с переполнением исключения в отдельных случаях.
27 Для активизации этого флага в Visual Studio 2012 необходимо открыть страницу свойств проекта, перейти на вкладку Build (Построение), щелкнуть на кнопке Advanced (Дополнительно) и в открывшемся диалоговом окне отметить флажок Check for arithmetic overflow/underflow (Проверять арифметические переполнения и потери точности):
28 В пространстве имен System имеется класс Convert, который тоже может применяться для расширения и сужения данных: byte sum = Convert.ToByte(var1 + var2); Одно из преимуществ подхода с применением класса System.Convert связано с тем, что он позволяет выполнять преобразования между типами данных нейтральным к языку образом (например, синтаксис приведения типов в Visual Basic полностью отличается от предлагаемого для этой цели в С#). Однако, поскольку в С# есть операция явного преобразования, использование класса Convert для преобразования типов данных обычно является делом вкуса.
29 Ссылочные типы классделегатмассивинтерфейс Тип, определенный как класс, делегат, массив или интерфейс, является ссылочным типом. Во время выполнения при объявлении переменной ссылочного типа переменная содержит значение null до явного создания экземпляра объекта с помощью оператора new или назначения его объекту, который был создан в другом месте, с помощью new, как показано в приведённом ниже примере: MyClass mc = new MyClass(); MyClass mc2 = mc; При создании объекта память размещается в управляемой куче, и переменная хранит только ссылку на расположение объекта.
30 сборка мусора Для типов в управляемой куче требуются служебные данные и при их размещении, и при их удалении для автоматического управления памятью среды CLR (сборка мусора). Сборка мусора в высокой степени оптимизирована, и в большинстве случаев не создает проблем с производительностью.
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.