Pragma warning 17 страница. static void Main() { Color c = Color.Red; PrintColor(c); PrintColor(Color.Blue); } }
static void Main() { Каждый тип перечисления имеет соответствующий целый тип, называемый базовым типом; типа перечисления. Если для перечисляемого типа явно не объявлен базовый тип, в качестве базового используется тип int. Формат хранения и диапазон возможных значений перечисляемого типа определяются его базовым типом. Набор значений перечисляемого типа может включать его члены, но не ограничивается только ими. В частности, любое значение базового типа может быть приведено к перечисляемому типу и является отдельным допустимым значением такого типа. В следующем примере объявляется перечисляемый тип Alignment, базовым для которого является тип sbyte. enum Alignment: sbyte Как показано в приведенном выше примере, объявление члена перечисляемого типа может включать константное выражение, определяющее значение такого члена. Значение константы для каждого члена должно принадлежать диапазону базового типа. Если в объявлении перечисляемого типа значение не задается явно, первому члену типа присваивается нулевое значение, а каждому последующему члену — значение текстуально предшествующего ему члена, увеличенное на единицу. Значения перечисляемых типов могут быть преобразованы к значениям целых типов (и наоборот) с помощью приведений типов. Пример: int i = (int)Color.Blue; // int i = 2; В качестве значения по умолчанию для любого перечисляемого типа используется целое нулевое значение, преобразованное к перечисляемому типу. Если переменные автоматически инициализируются с использованием значений по умолчанию, такие значения присваиваются переменным перечисляемого типа. Чтобы обеспечить доступность значений по умолчанию перечисляемого типа, литерал 0 неявно преобразуется к любому перечисляемому типу. Таким образом, допускаются выражения следующего вида. Color c = 0; 1.11 Делегаты; Тип делегата; представляет собой ссылки на методы с конкретным списком параметров и типом возвращаемого значения. С помощью делегатов методы обрабатываются как сущности, которым можно передавать параметры и которые можно присваивать переменным. Понятие делегата близко к понятию указателя на функцию, используемому в некоторых других языках. Однако делегаты, в отличие от указателей на функции, представляют собой пример объектно-ориентированного и строго типизированного подхода к программированию. В следующем примере объявляется и используется тип делегата Function. using System; delegate double Function(double x); class Multiplier public Multiplier(double factor) { public double Multiply(double x) { class Test static double[] Apply(double[] a, Function f) { static void Main() { double[] squares = Apply(a, Square); double[] sines = Apply(a, Math.Sin); Multiplier m = new Multiplier(2.0); Экземпляр типа делегата Function может ссылаться на любой метод, который принимает аргумент и возвращает значение типа double. Метод Apply применяет заданную функцию Function к элементам массива double[] и возвращает массив double[], содержащий результаты. В методе Main метод Apply используется для применения трех различных функций к массиву double[]. Делегат может ссылаться как на статический метод (например, Square или Math.Sin в предыдущем примере), так и на метод экземпляра (например, m.Multiply в предыдущем примере). Делегат, ссылающийся на метод экземпляра, также ссылается на конкретный объект. При вызове такого метода экземпляра с помощью делегата этот объект становится объектом this. Делегаты также могут создаваться с помощью анонимных функций, которые представляют собой «встроенные методы», создаваемые в процессе выполнения. Анонимные функции могут видеть локальные переменные окружающих их методов. Таким образом, приведенный выше пример множителя может быть записан проще с использованием класса Multiplier: double[] doubles = Apply(a, (double x) => x * 2.0); Интересной и полезной особенностью делегата является то, что для него неважен тип класса или метода, на который он ссылается. Единственным требованием является наличие у метода, на который ссылается делегат, такого же числа параметров и типа возвращаемого значения. 1.12 Атрибуты; Типы, члены и другие сущности C# поддерживают модификаторы, которые управляют определенными аспектами их поведения. Например, доступность метода управляется с помощью модификаторов public, protected, internal и private. Благодаря этой возможности в C# пользовательские типы декларативных сведений могут быть вложены в сущности программы и извлекаться во время выполнения. Такие дополнительные декларативные сведения задаются в программе посредством определения и использования атрибутов;. В следующем примере атрибут HelpAttribute присоединяется к сущностям программы и предоставляет ссылки на связанную с ними документацию. using System; public class HelpAttribute: Attribute public HelpAttribute(string url) { public string Url { public string Topic { Все классы атрибутов наследуются от базового класса System.Attribute, предоставляемого платформой.NET Framework. Чтобы применить атрибут, необходимо указать его имя и любые другие аргументы в квадратных скобках непосредственно перед связанным объявлением. Если имя атрибута заканчивается словом Attribute, при ссылке на него эту часть имени можно опустить. Например, атрибут HelpAttribute можно использовать следующим образом. [Help("http://msdn.microsoft.com/.../MyClass.htm")] В этом примере атрибут HelpAttribute присоединяется к классу Widget, а другой атрибут HelpAttribute — к методу Display класса. Общие конструкторы класса атрибута управляют сведениями, которые предоставляются при вложении атрибута в сущность программы. Дополнительные сведения предоставляются посредством ссылки на открытые свойства для чтения и записи класса атрибута (например, ссылка на свойства Topic в предыдущем примере).
|