Методы описания интерфейса в программной среде С#

Упрощенная форма объявления интерфейса. Алгоритм определения переменных ссылочного интерфейсного вида. Перечисление как определяемый пользователем целочисленный тип. Примеры явной реализации интерфейсного метода. Операторы объекта структуры в C#.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 14.03.2014
Размер файла 565,5 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru

Размещено на http://www.allbest.ru

1. Интерфейсы

Для начала ознакомимся с формальным определением типа интерфейса. Интерфейс (interface) представляет собой не более чем просто именованный набор абстрактных членов.

Абстрактные методы являются чистым протоколом, поскольку не имеют никакой стандартной реализации. Конкретные члены, определяемые интерфейсом, зависят от того, какое поведение моделируется с его помощью. Это действительно так. Интерфейс выражает поведение, которое данный класс или структура может избрать для поддержки. Более того, каждый класс (или структура) может поддерживать столько интерфейсов, сколько необходимо, и, следовательно, тем самым поддерживать множество поведений.

Нетрудно догадаться, что в библиотеках базовых классов .NET поставляются сотни предопределенных типов интерфейсов, которые реализуются в различных классах и структурах. Например, в состав ADO.NET входит множество поставщиков данных, которые позволяют взаимодействовать с определенной системой управления базами данных. Это означает, что в ADO.NET на выбор доступно множество объектов соединения (SqlConnection, OracleConnection, OdbcConnection и т.д.).

В интерфейсе ни у одного из методов не должно быть тела. Это означает, что в интерфейсе вообще не предоставляется никакой реализации. В нем указывается только, что именно следует делать, но не как это делать. Как только интерфейс будет определен, он может быть реализован в любом количестве классов. Кроме того, в одном классе может быть реализовано любое количество интерфейсов.

Для реализации интерфейса в классе должны быть предоставлены тела (т.е. конкретные реализации) методов, описанных в этом интерфейсе. Каждому классу предоставляется полная свобода для определения деталей своей собственной реализации интерфейса. Следовательно, один и тот же интерфейс может быть реализован в двух классах по-разному. Тем не менее в каждом из них должен поддерживаться один и тот же набор методов данного интерфейса. А в том коде, где известен такой интерфейс, могут использоваться объекты любого из этих двух классов, поскольку интерфейс для всех этих объектов остается одинаковым. Благодаря поддержке интерфейсов в С# может быть в полной мере реализован главный принцип полиморфизма: один интерфейс -- множество методов.

Интерфейсы объявляются с помощью ключевого слова interface. Ниже приведена упрощенная форма объявления интерфейса:

interface имя{

возвращаемый_тип имя_метода_1 (список_параметров);

возвращаемый_тип имя_метода_2 (список_параметров);

// ...

возвращаемый_тип имя_метода_N (список_параметров);

}

где имя -- это конкретное имя интерфейса. В объявлении методов интерфейса используются только их возвращаемый_тип и сигнатура. Они, по существу, являются абстрактными методами. Как пояснялось выше, в интерфейсе не может быть никакой реализации. Поэтому все методы интерфейса должны быть реализованы в каждом классе, включающем в себя этот интерфейс. В самом же интерфейсе методы неявно считаются открытыми, поэтому доступ к ним не нужно указывать явно.

Помимо методов, в интерфейсах можно также указывать свойства, индексаторы и события. Интерфейсы не могут содержать члены данных. В них нельзя также определить конструкторы, деструкторы или операторные методы. Кроме того, ни один из членов интерфейса не может быть объявлен как static.

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

class имя_класса : имя_интерфейса {

// тело класса

}

где имя_интерфейса -- это конкретное имя реализуемого интерфейса. Если уж интерфейс реализуется в классе, то это должно быть сделано полностью. В частности, реализовать интерфейс выборочно и только по частям нельзя.

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

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

Давайте рассмотрим пример:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication1

{

// Создаем два интерфейса, описывающих абстрактные методы

// арифметических операций и операций Sqrt и Sqr

public interface IArOperation

{

// Определяем набор абстрактных методов:

int Sum();

int Otr();

int Prz();

int Del();

}

public interface ISqrSqrt

{

int Sqr(int x);

int Sqrt(int x);

}

// Данный класс реализует интерфейс IArOperation

class A : IArOperation

{

int My_x, My_y;

public int x

{

set { My_x = value; }

get { return My_x; }

}

public int y

{

set { My_y = value; }

get { return My_y; }

}

public A() { }

public A(int x, int y)

{

this.x = x;

this.y = y;

}

// Реализуем методы интерфейса

public virtual int Sum()

{

return x + y;

}

public int Otr()

{

return x - y;

}

public int Prz()

{

return x * y;

}

public int Del()

{

return x / y;

}

// В данном классе так же можно реализовать собственные методы

public virtual void rewrite()

{

Console.WriteLine("Переменная x: {0}\nПеременная y: {1}",x,y);

}

}

// Данный класс унаследован от класса А, но при этом в нем не нужно

// заново реализовывать интерфейс, но при этом можно переопределить

// некоторые его методы

class Aa : A

{

public int z;

public Aa(int z, int x, int y)

: base(x, y)

{

this.z = z;

}

// Переопределим метод Sum

public override int Sum()

{

return base.x + base.y + z;

}

public override void rewrite()

{

base.rewrite();

Console.WriteLine("Переменная z: " + z);

}

}

// Данный класс унаследован от класса А, и при этом

// реализует интерфейс ISqrSqrt

class Ab : A, ISqrSqrt

{

public int Sqr(int x)

{

return x * x;

}

public int Sqrt(int x)

{

return (int)Math.Sqrt((double)(x));

}

}

class Program

{

static void Main()

{

A obj1 = new A(x: 10, y: 12);

Console.WriteLine("obj1: ");

obj1.rewrite();

Console.WriteLine("{0} + {1} = {2}",obj1.x,obj1.y,obj1.Sum());

Console.WriteLine("{0} * {1} = {2}", obj1.x, obj1.y, obj1.Prz());

Aa obj2 = new Aa(z: -3, x: 10, y: 14);

Console.WriteLine("\nobj2: ");

obj2.rewrite();

Console.WriteLine("{0} + {1} + {3} = {2}", obj2.x, obj2.y, obj2.Sum(), obj2.z);

Console.ReadLine();

}

}

}

Рис. 1

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

Рис. 2

2. Интерфейсные ссылки

Как это ни покажется странным, но в С# допускается объявлять переменные ссылочного интерфейсного типа, т.е. переменные ссылки на интерфейс. Такая переменная может ссылаться на любой объект, реализующий ее интерфейс. При вызове метода для объекта посредством интерфейсной ссылки выполняется его вариант, реализованный в классе данного объекта. Этот процесс аналогичен применению ссылки на базовый класс для доступа к объекту производного класса.

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

using System;

namespace ConsoleApplication1

{

public interface IInfo

{

void uiName();

void uiFamily();

void uiAge();

}

class UI : IInfo

{

string Name, Family;

int Age;

public UI(string Name, string Family, int Age)

{

this.Name = Name;

this.Family = Family;

this.Age = Age;

}

// Реализуем интерфейс

public void uiName()

{

Console.WriteLine("Имя пользователя: " + Name);

}

public void uiFamily()

{

Console.WriteLine("Фамилия: " + Family);

}

public void uiAge()

{

Console.WriteLine("Возвраст: " + Age);

}

// Собственный метод класса UI

public void allInfo()

{

Console.WriteLine(Name + " " + Family + " " + Age);

}

}

class Program

{

static void Main()

{

UI ui1 = new UI(Name: "Alexandr", Family: "Erohin", Age: 26);

// Создадим ссылку на интерфейс

IInfo obj;

//Используем ссылку на объект ui1

obj = ui1;

obj.uiName();

obj.uiFamily();

obj.uiAge();

// Вызов собственного метода не разрешается:

// obj.allInfo();

Console.ReadLine();

}

}

}

Рис. 3

Ключевое слово as.

Определить, поддерживает ли данный тип тот или иной интерфейс, можно с использованием ключевого слова as. Если объект удается интерпретировать как указанный интерфейс, то возвращается ссылка на интересующий интерфейс, а если нет, то ссылка null. Следовательно, перед продолжением в коде необходимо предусмотреть проверку на null.

В предыдущем примере, в методе Main() можно добавить следующую проверку:

IInfo obj = ui1 as IInfo;

if (obj != null)

Console.WriteLine("Тип UI поддерживает интерфейс IInfo");

else

Console.WriteLine(":(");

Обратите внимание, что в случае применения ключевого слова as использовать логику try/catch нет никакой необходимости, поскольку возврат ссылки, отличной от null, означает, что вызов осуществляется с использованием действительной ссылки на интерфейс.

Ключевое слово is.

Проверить, был ли реализован нужный интерфейс, можно также с помощью ключевого слова is. Если запрашиваемый объект не совместим с указанным интерфейсом, возвращается значение false, а если совместим, то можно спокойно вызывать члены этого интерфейса без применения логики try/catch.

if (ui1 is IInfo)

Console.WriteLine("Тип UI поддерживает интерфейс IInfo");

else

Console.WriteLine(":(");

3. Интерфейсные свойства и индексаторы

Интерфейсные свойства

Аналогично методам, свойства указываются в интерфейсе вообще без тела. Ниже приведена общая форма объявления интерфейсного свойства:

// Интерфейсное свойство

тип имя{

get;

set;

}

Очевидно, что в определении интерфейсных свойств, доступных только для чтения или только для записи, должен присутствовать единственный аксессор: get или set соответственно.

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

Давайте рассмотрим пример:

using System;

namespace ConsoleApplication1

{

interface IUserInfo

{

string Name

{

get;

set;

}

}

class UI : IUserInfo

{

string myName;

public string Name

{

set

{

myName = value;

}

get

{

return myName;

}

}

}

class Program

{

static void Main()

{

UI user1 = new UI();

user1.Name = "Alexandr";

Console.ReadLine();

}

}

}

В данном примере в классе UI реализуется свойство интерфейса IUserInfo.

Интерфейсные индексаторы

В интерфейсе можно также указывать индексаторы. Ниже приведена общая форма объявления интерфейсного индексатора:

// Интерфейсный индексатор

тип_элемента this[int индекс]{

get;

set;

}

Как и прежде, в объявлении интерфейсных индексаторов, доступных только для чтения или только для записи, должен присутствовать единственный аксессор: get или set соответственно. Давайте добавим в предыдущий пример реализацию индексатора:

using System;

namespace ConsoleApplication1

{

interface IUserInfo

{

string Name

{

get;

set;

}

string this[int index]

{

get;

set;

}

}

class UI : IUserInfo

{

string myName;

public string Name

{

set

{

myName = value;

}

get

{

return myName;

}

}

public string this[int index]

{

set { myName = value; }

get { return myName; }

}

}

class Program

{

static void Main()

{

UI user1 = new UI();

user1.Name = "Alexandr";

user1[5] = "Dmitryi";

user1[10] = "Alexey";

Console.ReadLine();

}}}

4. Наследование интерфейсов

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

Таким образом, интерфейсы могут быть организованы в иерархии. Как и в иерархии классов, в иерархии интерфейсов, когда какой-то интерфейс расширяет существующий, он наследует все абстрактные члены своего родителя (или родителей). Конечно, в отличие от классов, производные интерфейсы никогда не наследуют саму реализацию. Вместо этого они просто расширяют собственное определение за счет добавления дополнительных абстрактных членов.

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

using System;

namespace ConsoleApplication1

{

public interface A

{

int Sum();

}

// Унаследованный интерфейс

public interface B : A

{

int Del();

}

class MyOperation : B

{

int x = 10, y = 5;

public int Sum()

{

return x + y;

}

public int Del()

{

return x / y;

}

}

class Program

{

static void Main()

{

}

}

}

Обратите внимание, что класс MyOperation реализует методы обоих интерфейсов, иначе возникла бы ошибка при компиляции:

Рис. 4

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

5. Явная реализация интерфейса

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

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

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

using System;

namespace ConsoleApplication1

{

public interface IName

{

void WriteName();

}

public interface INameFamily

{

// Объявляем в данном интерфейсе такой же метод

void WriteName();

void WriteFamily();

}

public interface IUserInfo : INameFamily

{

// Обязательно нужно указать ключевое слово new

// чтобы не скрывались методы базового интерфейса

new void WriteName();

void WriteUserInfo();

}

// Класс, реализующий два интерфейса

class UserInfo : IUserInfo,IName

{

string ShortName, Family, Name;

public UserInfo(string Name, string Family, string ShortName)

{

this.Name = Name;

this.Family = Family;

this.ShortName = ShortName;

}

// Используем явную реализацию интерфейсов

// для исключения неоднозначности

void IName.WriteName()

{

Console.WriteLine("Короткое имя: " + ShortName);

}

void INameFamily.WriteFamily()

{

Console.WriteLine("Фамилия: " + Family);

}

void INameFamily.WriteName()

{

Console.WriteLine("Полное имя: " + Name);

}

void IUserInfo.WriteName() { }

public void WriteUserInfo()

{

UserInfo obj = new UserInfo(Name, Family, ShortName);

// Для использования закрытых методов необходимо

// создать интерфейсную ссылку

IName link1 = (IName)obj;

link1.WriteName();

INameFamily link2 = (INameFamily)obj;

link2.WriteName();

link2.WriteFamily();

IUserInfo link3 = (IUserInfo)obj;

link3.WriteName();

}

}

class Program

{

static void Main()

{

UserInfo obj = new UserInfo(Name: "Alexandr", ShortName: "Alex", Family: "Erohin");

obj.WriteUserInfo();

Console.ReadLine();

}

}

}

Рис. 5

Важно уяснить, что интерфейсы являются фундаментальным компонентом .NET Framework. Какого бы типа приложение не разрабатывалось (веб-приложение, приложение с настольным графическим интерфейсом, библиотека доступа к данными и т.п.), работа с интерфейсами будет обязательной частью этого процесса. Подводя итог всему изложенному, отметим, что интерфейсы могут приносить чрезвычайную пользу в следующих случаях:

При наличии единой иерархии, в которой только какой-то набор производных типов поддерживает общее поведение.

При необходимости моделировать общее поведение, которое должно встречаться в нескольких иерархиях, не имеющих общего родительского класса помимо System.Object.

6. Структуры

Как вам должно быть уже известно, классы относятся к ссылочным типам данных. Это означает, что объекты конкретного класса доступны по ссылке, в отличие от значений простых типов, доступных непосредственно. Но иногда прямой доступ к объектам как к значениям простых типов оказывается полезно иметь, например, ради повышения эффективности программы. Ведь каждый доступ к объектам (даже самым мелким) по ссылке связан с дополнительными издержками на расход вычислительных ресурсов и оперативной памяти.

Для разрешения подобных затруднений в С# предусмотрена структура, которая подобна классу, но относится к типу значения, а не к ссылочному типу данных. Т.е. структуры отличаются от классов тем, как они сохраняются в памяти и как к ним осуществляется доступ (классы -- это ссылочные типы, размещаемые в куче, структуры -- типы значений, размещаемые в стеке), а также некоторыми свойствами (например, структуры не поддерживают наследование). Из соображений производительности вы будете использовать структуры для небольших типов данных. Однако в отношении синтаксиса структуры очень похожи на классы.

Главное отличие состоит в том, что при их объявлении используется ключевое слово struct вместо class. Ниже приведена общая форма объявления структуры:

struct имя : интерфейсы {

// объявления членов

}

где имя обозначает конкретное имя структуры.

Как и у классов, у каждой структуры имеются свои члены: методы, поля, индексаторы, свойства, операторные методы и события. В структурах допускается также определять конструкторы, но не деструкторы. В то же время для структуры нельзя определить конструктор, используемый по умолчанию (т.е. конструктор без параметров). Дело в том, что конструктор, вызываемый по умолчанию, определяется для всех структур автоматически и не подлежит изменению. Такой конструктор инициализирует поля структуры значениями, задаваемыми по умолчанию. А поскольку структуры не поддерживают наследование, то их члены нельзя указывать как abstract, virtual или protected.

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

Давайте рассмотрим пример использования структур:

using System;

namespace ConsoleApplication1

{

// Создадим структуру

struct UserInfo

{

public string Name;

public byte Age;

public UserInfo(string Name, byte Age)

{

this.Name = Name;

this.Age = Age;

}

public void WriteUserInfo()

{

Console.WriteLine("Имя: {0}, возраст: {1}",Name,Age);

}

}

class Program

{

static void Main()

{

UserInfo user1 = new UserInfo("Alexandr", 26);

Console.Write("user1: ");

user1.WriteUserInfo();

UserInfo user2 = new UserInfo("Elena",22);

Console.Write("user2: ");

user2.WriteUserInfo();

// Показать главное отличие структур от классов

user1 = user2;

user2.Name = "Natalya";

user2.Age = 25;

Console.Write("\nuser1: ");

user1.WriteUserInfo();

Console.Write("user2: ");

user2.WriteUserInfo();

Console.ReadLine();

}

}

}

Рис. 6

Обратите внимание, когда одна структура присваивается другой, создается копия ее объекта. В этом заключается одно из главных отличий структуры от класса. Когда ссылка на один класс присваивается ссылке на другой класс, в итоге ссылка в левой части оператора присваивания указывает на тот же самый объект, что и ссылка в правой его части. А когда переменная одной структуры присваивается переменной другой структуры, создается копия объекта структуры из правой части оператора присваивания.

Поэтому, если бы в предыдущем примере использовался класс UserInfo вместо структуры, получился бы следующий результат:

Рис. 7

7. Назначение структур

В связи с изложенным выше возникает резонный вопрос: зачем в С# включена структура, если она обладает более скромными возможностями, чем класс? Ответ на этот вопрос заключается в повышении эффективности и производительности программ. Структуры относятся к типам значений, и поэтому ими можно оперировать непосредственно, а не по ссылке. Следовательно, для работы со структурой вообще не требуется переменная ссылочного типа, а это означает в ряде случаев существенную экономию оперативной памяти.

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

Любопытно, что в С++ также имеются структуры и используется ключевое слово struct. Но эти структуры отличаются от тех, что имеются в С#. Так, в С++ структура относится к типу класса, а значит, структура и класс в этом языке практически равноценны и отличаются друг от друга лишь доступом по умолчанию к их членам, которые оказываются закрытыми для класса и открытыми для структуры. А в С# структура относится к типу значения, тогда как класс -- к ссылочному типу.

интерфейсный ссылочный целочисленный

8. Перечисления

Перечисление (enumeration) -- это определяемый пользователем целочисленный тип. Когда вы объявляете перечисление, то специфицируете набор допустимых значений, которые могут принимать экземпляры перечислений. Но мало того -- этим значениям еще должны быть присвоены имена, понятные для пользователей. Если где-то в коде попытаться присвоить экземпляру перечисления значение, не входящее в список допустимых, компилятор выдаст ошибку.

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

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

Перечисления делают код яснее, позволяя обращаться к целым значениям, называя их осмысленными именами вместо малопонятных "магических" чисел.

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

Перечислимый тип данных объявляется с помощью ключевого слова enum. Ниже приведена общая форма объявления перечисления:

enum имя {список_перечисления};

где имя -- это имя типа перечисления, а список_перечисления -- список идентификаторов, разделяемый запятыми.

Следует особо подчеркнуть, что каждая символически обозначаемая константа в перечислении имеет целое значение. Тем не менее неявные преобразования перечислимого типа во встроенные целочисленные типы и обратно в С# не определены, а значит, в подобных случаях требуется явное приведение типов. Кроме того, приведение типов требуется при преобразовании двух перечислимых типов. Но поскольку перечисления обозначают целые значения, то их можно, например, использовать для управления оператором выбора switch или же оператором цикла for.

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

Давайте рассмотрим пример использования перечислений:

using System;

namespace ConsoleApplication1

{

// Создать перечисление

enum UI : long { Name, Family, ShortName = 5, Age, Sex }

class Program

{

static void Main()

{

UI user1;

for (user1 = UI.Name; user1 <= UI.Sex; user1++)

Console.WriteLine("Элемент: \"{0}\", значение {1}",user1,(int)user1);

Console.ReadLine();

}

}

}

Рис. 8

Значение одной или нескольких символически обозначаемых констант в перечислении можно задать с помощью инициализатора. Для этого достаточно указать после символического обозначения отдельной константы знак равенства и целое значение. Каждой последующей константе присваивается значение, которое на единицу больше значения предыдущей инициализированной константы. В приведенном выше примере инициализируется константа ShortName.

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

Изменять базовый тип перечислений удобно в случае создания таких приложений .NET, которые будут развертываться на устройствах с небольшим объемом памяти (таких как поддерживающие .NET сотовые телефоны или устройства PDA), чтобы экономить память везде, где только возможно. Естественно, если для перечисления в качестве базового типа указан byte, каждое значение в этом перечислении ни в коем случае не должно выходить за рамки диапазона его допустимых значений.

Перечисления очень широко применяются во всех библиотеках базовых классов .NET. Например, в ADO.NET множество перечислений используется для обозначения состояния соединения с базой данных (например, открыто оно или закрыто) и состояния строки в DataTable (например, является она измененной, новой или отсоединенной). Поэтому в случае применения любых перечислений следует всегда помнить о наличии возможности взаимодействовать с парами "имя/значение" в них с помощью членов System.Enum.

Размещено на Allbest.ru

...

Подобные документы

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

    дипломная работа [2,0 M], добавлен 14.01.2012

  • Общая характеристика и функциональное назначение проектируемого программного обеспечения, требования к нему. Разработка и описание интерфейса клиентской и серверной части. Описание алгоритма и программной реализации приложения. Схема базы данных.

    курсовая работа [35,4 K], добавлен 12.05.2013

  • Состав DЕLPHI проекта. Алгоритм сортировки вектора. Метод сортировки файла. Сценарий интерфейсного диалога пользователя с программой. Поиск и вычисление времени, затраченного на поиск и сортировку. Исходный текст модуля Project.dpr, MainForm.pas.

    курсовая работа [827,4 K], добавлен 07.11.2010

  • Алгоритмическое представление и описание правил игры "Эволюция". Построение диаграммы прецедентов. Разработка графического интерфейса пользователя. Реализация интерфейса в среде Unity. Структура файла сохранения игры. Проектирование поведения компьютера.

    дипломная работа [3,3 M], добавлен 18.02.2017

  • Создание блок-схемы алгоритма и реализующей его программы, снабженных пояснениями, для решения задач. Реализация программы в среде Delphi как проекта консольного приложения. Основные алгоритмические структуры, соответствующие операторы для их реализации.

    контрольная работа [447,4 K], добавлен 08.10.2012

  • Общая характеристика сетевой игры с несколькими клиентами в программной среде MS Visual Studio 2010 на языке программирования C++ с использованием функций работы с сокетами. Реализация системного сервиса, разработки интерфейса, алгоритм его тестирования.

    курсовая работа [495,3 K], добавлен 06.01.2013

  • Особенности процесса взаимодействия пользователя с компьютером. Графический интерфейс ОС Windows, его преимущества и недостатки. Основы простейшего SILK-интерфейса. Основные черты и специфика структуры WIMP-интерфейса. Общепринятые соглашения для меню.

    реферат [26,8 K], добавлен 02.10.2012

  • Методы обработки информации при решении прикладных задач. Математическая модель задачи. Блок-схема алгоритма программы. Компоненты, которые используются для работы в программе: элементы интерфейса; процедуры; операторы. Текст программы с пояснениями.

    курсовая работа [954,0 K], добавлен 07.01.2011

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

    контрольная работа [681,9 K], добавлен 13.01.2010

  • Методы и алгоритмы построения инструментариев для разработки систем управления проектами посредством Web интерфейса. Составление модели обработки информации "как должно быть". Годовой экономический эффект и прочие показатели экономической эффективности.

    дипломная работа [1,1 M], добавлен 28.09.2015

  • Формирование на экране меню для выбора функций. Элементы пользовательского интерфейса. Описание внутренних переменных, входных и выходных данных языка программирования Си. Выбор пользователем функции. Создание программы "Список коммерческих банков".

    курсовая работа [491,9 K], добавлен 17.03.2015

  • Язык программирования Pascal и его турбооболочка. Аналитический обзор игрового программного обеспечения. Функции модуля Crt. Постановка задачи создания несложной игровой программы "Турбозмей", алгоритм реализации и описание пользовательского интерфейса.

    курсовая работа [100,4 K], добавлен 15.05.2014

  • Исследование особенностей разработки линейных алгоритмов и их реализации в среде Delphi. Составление тестов для проверки программы. Характеристика основных элементов интерфейса, компонентов, значения их свойств. Построение графической схемы алгоритма.

    лабораторная работа [316,6 K], добавлен 08.11.2012

  • Основные правила разработки интерфейса пользователя. Создание базы данных с использованием разработанных моделей. Кодирование модулей программной системы с целью создания прототипа. Первичное окно при запуске программы. Защита от потери информации.

    лабораторная работа [857,8 K], добавлен 13.06.2014

  • Общие сведения о функциях, их структура. Области видимости и классы памяти переменных в функциях. Классификация видов памяти, выделяемой под переменные и константы. Примеры объявления глобальных и локальных переменных. Обращение к функции и ее прототип.

    презентация [64,6 K], добавлен 09.12.2013

  • Требование к структуре данных в базе, описание ее вида, содержание объектов. Используемые форматы данных. Алгоритмы и их особенности. Функциональное описание разработки. Описание пользовательского интерфейса. Контрольные примеры, временные характеристики.

    курсовая работа [1,5 M], добавлен 06.04.2016

  • Технология разработки пользовательского интерфейса в среде Delphi. Создание таблицы, меню, форм для ввода и редактирования данных. Принципы организации меню как элемента интерфейса пользователя. Реализация сортировки, фильтрации, вычислений в таблице.

    курсовая работа [1,6 M], добавлен 13.11.2012

  • Критерии и порядок выбора интерфейса веб-сайта. Характеристики, которые определяют успешность пользовательского интерфейса. Структура навигационной системы. Графический дизайн и выбор цветовой схемы. Техническая реализация интерфейса сайта на сегодня.

    реферат [164,8 K], добавлен 24.02.2011

  • Разработка приложения "Ведомость начисления заработной платы" в среде программирования C++Builder. Алгоритм и сценарий работы программы. Проектирование интерфейса пользователя. Написание программных модулей и результаты тестирования данной программы.

    курсовая работа [597,4 K], добавлен 31.01.2016

  • Обзор технологии COM (Component Object Technology). Особенности графического интерфейса пользователя и методы его реализации. Интерфейс операционных систем Microsoft Windows: работа с папками, файлами и окнами, использование буфера обмена, проводник.

    контрольная работа [6,4 M], добавлен 16.04.2011

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.