Задание типов при объявлении переменных




Когда вы объявляете в программе переменную или константу, для нее нужно задать тип либо использовать ключевое слово var, чтобы компилятор определил тип самостоятельно. В следующем примере показаны некоторые объявления переменных, использующие встроенные числовые типы и сложные пользовательские типы:

C#

// Declaration only:float temperature;string name;MyClass myClass; // Declaration with initializers (four examples):char firstLetter = 'C';var limit = 3;int[] source = { 0, 1, 2, 3, 4, 5 };var query = from item in source where item <= limit select item;

Типы для параметров и возвращаемых значений метода задаются в сигнатуре метода. Далее представлена сигнатура метода, который требует значение int в качестве входного аргумента и возвращает строку:

C#

public string GetName(int ID){ if (ID < names.Length) return names[ID]; else return String.Empty;}private string[] names = { "Spencer", "Sally", "Doug" };

После объявления переменной она не может быть повторно объявлена с новым типом, и ей нельзя присвоить значение, несовместимое с ее объявленным типом. Например, нельзя объявить переменную типа int и затем присвоить ей логическое значение true. Однако значения могут быть преобразованы в другие типы, например при сохранении в другие переменные или при передаче в качестве аргументов метода. Если преобразование типов не приводит к потере данных, она выполняется компилятором автоматически. Для преобразования, которое может привести к потере данных, необходимо выполнить приведение в исходном коде.

Встроенные типы

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

Типы значений

Типы значений являются производными от System.ValueType, который является производным от System.Object. Типы, производные от System.ValueType, имеют особое поведение в среде CLR. Переменные с типами значения напрямую содержат свои значения, то есть для них всегда выделяется память из стека в том контексте, где объявлена эта переменной. Нет раздельного размещения в куче или накладных расходов при сборке мусора для переменных типа значения.

Существует две категории типов значений: структура и перечисление.

Встроенные числовые типы являются структурами и имеют свойства и методы, к которым можно обращаться.

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

// Static method on type Byte. byte b = Byte.MaxValue;

Но объявление и присвоение значений вы выполняете для них так, как если бы они были простыми нестатистическими типами.

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

byte num = 0xA; int i = 5; char c = 'Z';

Типы значений являются запечатанными, что означает, например, что нельзя наследовать тип от System.Int32 и нельзя определить структуру для наследования от любого пользовательского класса или структуры, поскольку структура может наследовать только от System.ValueType. Тем не менее структура может реализовывать один или несколько интерфейсов. Можно выполнить приведение типа структуры к типу интерфейса. При этом выполняется операция упаковки-преобразования, которая создает для структуры оболочку в виде объекта ссылочного типа, размещенного в управляемой куче. Операции упаковки-преобразования возникают при передаче типа значения в метод, принимающий System.Object в качестве входного параметра. Дополнительные сведения см. в статье Boxing and Unboxing (Упаковка–преобразование и распаковка–преобразование).

Используйте ключевое слово struct, чтобы создать собственные пользовательские типы значений. Как правило, структура используется как контейнер для небольшого набора связанных переменных, как показано в следующем примере:

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

public struct CoOrds{ public int x, y; public CoOrds(int p1, int p2) { x = p1; y = p2; }}

Универсальные типы

Тип может быть объявлен с одним или несколькими параметрами типа вместо фактического типа (конкретного типа), который клиентский код предоставит при создании экземпляра этого типа. Такие типы называются универсальными типами. Например, тип платформы.NET Framework System.Collections.Generic.List<T> имеет один параметр типа, которому в соответствии с соглашением присвоено имя T. При создании экземпляра этого типа необходимо указать тип объектов, которые будут содержаться в списке. Например, так используется список строковых значений:

C#

List<string> stringList = new List<string>();stringList.Add("String example");// compile time error adding a type other than a string:stringList.Add(4);

Использование параметра типа позволяет повторно использовать один же класс для хранения элементов любого типа, не преобразовывая каждый элемент в объект. Универсальные классы коллекций называются строго типизированными коллекциями, так как компилятору известен конкретный тип элементов коллекции и он может выдать ошибку во время компиляции, если, к примеру, вы попытаетесь добавить целое число в объект strings, созданный в предыдущем примере.

Статические типы

Классы (но не структуры) могут быть объявлены как статические. Статический класс может содержать только статические члены. Для него нельзя создать экземпляр с помощью ключевого слова new. При запуске программы в память загружается одна копия такого класса. Доступ к его членам осуществляется через имя класса. Классы и структуры могут содержать статические члены. Дополнительные сведения см. в статье Статические классы и члены статических классов.

Статистический класс.

Статический класс в основном такой же, как и нестатический класс, но имеется одно отличие: нельзя создавать экземпляры статического класса. Другими словами, нельзя использовать ключевое слово new для создания переменной типа класса. Поскольку нет переменной экземпляра, доступ к членам статического класса осуществляется с использованием самого имени класса. Например, если имеется статический класс, называемый UtilityClass, имеющий открытый метод с именем MethodA, вызов метода выполняется, как показано в следующем примере:

C#

UtilityClass.MethodA();

Статический класс может использоваться как обычный контейнер для наборов методов, работающих на входных параметрах, и не должен возвращать или устанавливать каких-либо внутренних полей экземпляра. Например, в библиотеке классов.NET Framework статический класс System.Math содержит методы, выполняющие математические операции, без требования сохранять или извлекать данные, уникальные для конкретного экземпляра класса Math. Это значит, что члены класса применяются путем задания имени класса и имени метода, как показано в следующем примере.

C#

double dub = -3.14; Console.WriteLine(Math.Abs(dub)); Console.WriteLine(Math.Floor(dub)); Console.WriteLine(Math.Round(Math.Abs(dub))); // Output: // 3.14 // -4 // 3

Как и в случае с типами всех классов, сведения о типе для статического класса загружаются средой CLR.NET Framework, когда загружается программа, которая ссылается на класс. Программа не может точно указать, когда загружается класс. Однако гарантируется загрузка этого класса, инициализация его полей и вызов статического конструктора перед первым обращением к классу в программе. Статический конструктор вызывается только один раз, и статический класс остается в памяти на время существования домена приложения, в котором находится программа.

Ниже приведены основные возможности статического класса.

· Содержит только статические члены.

· Создавать его экземпляры нельзя.

· Является запечатанным.

· Не может содержать конструкторы экземпляров.

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

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

Пример

Ниже приведен пример статического класса, содержащего два метода, преобразующих температуру по Цельсию в температуру по Фаренгейту и наоборот.

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

public static class TemperatureConverter{ public static double CelsiusToFahrenheit(string temperatureCelsius) { // Convert argument to double for calculations. double celsius = Double.Parse(temperatureCelsius); // Convert Celsius to Fahrenheit. double fahrenheit = (celsius * 9 / 5) + 32; return fahrenheit; } public static double FahrenheitToCelsius(string temperatureFahrenheit) { // Convert argument to double for calculations. double fahrenheit = Double.Parse(temperatureFahrenheit); // Convert Fahrenheit to Celsius. double celsius = (fahrenheit - 32) * 5 / 9; return celsius; }} class TestTemperatureConverter{ static void Main() { Console.WriteLine("Please select the convertor direction"); Console.WriteLine("1. From Celsius to Fahrenheit."); Console.WriteLine("2. From Fahrenheit to Celsius."); Console.Write(":"); string selection = Console.ReadLine(); double F, C = 0; switch (selection) { case "1": Console.Write("Please enter the Celsius temperature: "); F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine()); Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F); break; case "2": Console.Write("Please enter the Fahrenheit temperature: "); C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine()); Console.WriteLine("Temperature in Celsius: {0:F2}", C); break; default: Console.WriteLine("Please select a convertor."); break; } // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); }}/* Example Output: Please select the convertor direction 1. From Celsius to Fahrenheit. 2. From Fahrenheit to Celsius.:2 Please enter the Fahrenheit temperature: 20 Temperature in Celsius: -6.67 Press any key to exit. */

Статический члены

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

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

Статические методы могут быть перегружены, но не переопределены, поскольку они относятся к классу, а не к экземпляру класса.

Несмотря на то, что поле не может быть объявлено как static const, поле const по своему поведению является статическим. Он относится к типу, а не к экземплярам типа. Поэтому к полям const можно обращаться с использованием той же нотации ClassName.MemberName, что и для статических полей. Экземпляр объекта не требуется.

C# не поддерживает статические локальные переменные (переменные, объявленные в области действия метода).

Для объявления статических методов класса используется ключевое слово static перед возвращаемым типом члена, как показано в следующем примере:

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

public class Automobile{ public static int NumberOfWheels = 4; public static int SizeOfGasTank { get { return 15; } } public static void Drive() { } public static event EventType RunOutOfGas; // Other non-static fields and properties...}

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

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

Automobile.Drive();int i = Automobile.NumberOfWheels;

Если класс содержит статические поля, должен быть указан статический конструктор, который инициализирует эти поля при загрузке класса.

Вызов статического метода генерирует инструкцию вызова в промежуточном языке Microsoft (MSIL), в то время как вызов метода экземпляра генерирует инструкцию callvirt, которая также проверяет наличие ссылок на пустые объекты. Однако в большинстве случаев разница в производительности двух видов вызовов несущественна.

 

Константы.

Константы — это постоянные значения, которые известны во время компиляции и не изменяются во время выполнения программы. Константы должны объявляться с модификатором const. Только встроенные типы C# (за исключением System.Object) можно объявлять как const. Список встроенных типов см. в таблице встроенных типов. Пользовательские типы, включая классы, структуры и массивы, не могут объявляться как const. Модификатор readonly позволяет создать класс, структуру или массив, которые инициализируются один раз (например, в конструкторе), и впоследствии изменить их нельзя.

C# не поддерживает методы, свойства или события const.

Тип перечисления позволяет определять именованные константы для целочисленных встроенных типов (например int, uint, long и т. д.). Дополнительные сведения см. в разделе Перечисление.

Константы должны инициализироваться сразу после объявления. Пример:

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

class Calendar1{ public const int months = 12;}

В этом примере константа months всегда имеет значение 12, и его не может изменить даже сам класс. На самом деле в случае, если компилятор встречает идентификатор константы в исходном коде C# (например, months), он подставляет значение литерала непосредственно в создаваемый им промежуточный язык (IL). Поскольку с константой в среде выполнения не связан адрес ни одной переменной, поля const не могут передаваться по ссылке и отображаться в выражении как левостороннее значение.

Несколько констант одного типа можно объявить одновременно, например:

C#

class Calendar2{ const int months = 12, weeks = 52, days = 365;}

Выражение, которое используется для инициализации константы, может ссылаться на другую константу, если не создает циклическую ссылку. Пример:

C#

class Calendar3{ const int months = 12; const int weeks = 52; const int days = 365; const double daysPerWeek = (double) days / (double) weeks; const double daysPerMonth = (double) days / (double) months;}

Доступ к константам осуществляется так, как если бы они были статическими полями, так как значение константы одинаково для всех экземпляров типа. Для их объявления не нужно ключевое слово static. Выражения, которые не относятся к классу, определяющему константу, должны включать имя класса, точку и имя константы для доступа к этой константе.

Пример:

C#

int birthstones = Calendar.months;

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-04-04 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: