Главное меню » Начинающим » C# для начинающих

C# для начинающих

C# — это язык с функциональностью C++, стилем программирования Java и моделью быстрой разработки приложений, позаимоствованной из BASIC. Если вы уже знаете C++, освоение синтаксиса C# займет у вас менее часа. Знакомство с Java даст вам существенное преимущество, так C# позаимствовал у Java структуру программы, концепции пакетов и «сборки мусора». Кроме того, при обсуждении конструкций языка C#, я буду считать, что вы знаете, C++.

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

В статье обсуждаются следующие аспекты языка C#:

  • Структура программы
  • Пространства имен
  • Переменные
  • Типы данных
  • Перечисления
  • Классы и структуры
  • Свойства
  • Модификаторы
  • Интерфейсы
  • Массивы
  • Индексаторы
  • Упаковка и распаковка
  • Параметры функции
  • Операторы
  • Делегаты
  • Наследование и полиморфизм
Структура программы

Как и C++, C# чувствителен к регистру. Точка с запятой (;) является разделителем операторов. В отличие от C++ в C#, к сожалению, нет отдельных файлов объявления (заголовчных файлов) и файлов реализации (cpp). Весь код (объявление класса и его реализация) помещается в один файл с расширением cs.

Вот, традиционная реализация ‘Hello world!’ на C#:
using System;

Все в C# помещается в класс, а классы в C # должны находится в каком-либо пространстве имен (так же, как файлы в папке). Как и C++, метод Main является точкой входа вашей программы. В C++ основная функция вашей программы называется main, тогда как C# основная функцияначинается с заглавной буквы М и назвается Main.
Нет необходимости ставить точку с запятой после блока, класса или определения структуры. Это было необходимо в C++, в C# это не требуется.

Пространства имен

Каждый класс находится в каком-либо пространстве имен. Термин пространство имен имеет в C# точно такое же значние, как b в C ++, но в C# мы используем пространства имен чаще, чем в C++. Вы можете получить доступ к классу в пространстве имен с использованием точки (.). В приведенной выше программе MyNameSpace — это пространство имен.

Теперь рассмотрим, как получить доступ к классу HelloWorld из какого-то другого класса в другом пространстве имен.

Теперь из вашего класса HelloWorld вы можете получить доступ к классу AnotherClass, вот таким образом:

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

Можно также определить вложенные пространства имен.

Ключевое слово Using

Директива #include заменена использованием ключевого слова using, за которым следует имя пространства имен. Так же, как это было продемонстрированно выше для пространства имен System. System является пространством имен базового уровня, в котором находятся все другие пространства имен и классы. Базовым класс для всех объектов в C# является класс Object из пространства имен System.

Переменные

Синтаксис объявления переменных в C# почти ничем не отличается от C++ за исключением следующих моментов:

  • Переменные в C# (в отличие от C++) всегда необходимо инициализировать перед тем, как начать их использовать, в противном случае вы получите ошибку времени компиляции. Следовательно, невозможно получить доступ к неинициализированой переменной.
  • Нельзя получить доступ к элементам массива через его индекс, если индексы указывает на элемент за пределами массива.
  • В C# нет глобальных переменных и функций, поэтому вместо них используются статические функции и статические переменные.
Типы данных

Все типы C# являются производными от базового класса Object. Существуют два типа типов данных:

  • Основные / встроенные типы
  • Определяемые пользователем типы

Ниже приводится таблица, в которой перечислены встроенные типы C#:

Тип Размер в байтах Описание Диапазон значений
byte 1 беззнаковый целочисленный тип/td> 0 : 255
sbyte 1 целочисленный тип со знаком -128 : 127
short 2 короткий целочисленный тип со знаком -32768 : 32767
ushort 2 короткий беззнаковый целочисленный тип 0 : 65535
int 4 целочисленный тип со знаком -2147483648 : 2147483647
uint 4 беззнаковый целочисленный тип 0 : 4294967295
long 8 длинныйй целочисленный тип со знаком -9223372036854775808 : 9223372036854775807
ulong 8 длинныйй беззнаковый целочисленный тип 0 : 18446744073709551615
float 4 число с плавающей точкой
double 8 число с плавающей точкой двойной точности
decimal 8 десятичный тип фиксированной точности
string Строка в кодировке Unicode
char Символ в кодировке Unicode
bool Целочисленный тип, который может иметь одно из двух значений: true или false.

Определяемые пользователем типы включает в себя:

  • Классы
  • Структуры
  • Интерфейсы

Все эти типы данных можно разделить на типы значений, еще называемые значимыми типами, (value types) и ссылочные типы (reference types). Важно понимать между ними различия.
К типам значений относятся типа данных, для котороых память выделяется на стеке. Это:

  • Целочисленные типы (byte, sbyte, char, short, ushort, int, uint, long, ulong)
  • Типы с плавающей точкой (float, double)
  • Тип decimal
  • Тип bool
  • Перечисления enum
  • Структуры (struct)

К ссылочным типам относятся типы, для которых память выделяется в «куче». Экземпляры ссылочных типов создаются с помощью оператора new, однако, в отличие от C++, в C# не существует оператор delete для ссылочных типо. В C#, память выделенная для ссылочных типов, автоматически освобождается сборщиком мусора, когда экземпляры этих типов выходят из области видимости. К таким типам относятся:

  • Тип object
  • Тип string
  • Классы (class)
  • Интерфейсы (interface)
  • Делегаты (delegate)
Перечисления

Перечисления в C# выглядят точно так же, как и в C++. Перечисление определяется с помощью ключевого слова enum. Например:

 

Классы и структуры

Классы и структуры в C# определяются так же, как и в C++, но, важно помнить о разнице в распределении памяти для классов и структур в C#. Память для объектов классов выделяются в «куче» (т.к. классы являются ссылочным типов) с помощью оператора new. Для структур память выделяется в стеке. Структуры в C# предназначениы для очень легких и небольших по объёму данных, для работы с которыми важна, прежде всего, скорость. Для «тяжелых» типов данных, вы необходимо использовать классы.
Пример:

 

Свойства

Если вы знакомы с объектно-ориентированным подходом к разработке, используемым в C++, вы должны иметь представление о свойствах классов. Свойствами в приведенном выше примере для класса Date являются day, month и year, для которых в C++, вы пишете Get и Set методы. C# обеспечивает более удобный, простой и прямолинейный способ доступа к свойствам класса. С учётом этого, класс Date из вышеприведенного примера может быть переписан вот так:

 

Модификаторы

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

Модификатор readonly

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

 

Модификатор sealed

Модификатор sealed запрещает использовать помеченный им класс в качестве базового при наследовании.

 

Модификатор unsafe

С помощью модификатора unsafe вы можете определить «небезопасный» контекст. Использование этого контекста необходимо, если вы собираетесь писать «небезопасный» код, напримерс использованием C++ указателей и т.п.

 

Интерфейсы

Если вы имеет представление о среде COM, вы сразу же поймет, что имеется в виду. Интерфейс является абстрактным базовым классом, содержащим только сигнатуры функций , реализация которых обеспечивается дочерним классом. В C# можно определить такие классы как интерфейсы с помощью ключевого слова interface. Библиотека .NET основана на таких интерфейсах. Так как в C#, вы не можете использовать множественное наследование классов, которое разрешено в C++, сущность множественного наследования достигается через использование интерфейсов. В C# дочерний класс может реализовать несколько интерфейсов.

 

Массивы

Массивы в C# гораздо удобнее, чем в C++. Память для массива в C# выделяются в куче и, таким образом, массивы являются ссылочными типами. Вы не можете получить доступ к элементу массиве используя индекс, указывающий за границы массива. Так что, C# избавляет вас от этого типа ошибок. Кроме того, в C# определны некоторые вспомогательные функции для итерации по элементам массива, например foreach. Разница между синтаксисом работы с массивами в C++ и C# в следующем:

  • Квадратные скобки должны находится после объявления типа массива, а не имени переменной
  • Память для массива всегда выделяется при помощи оператора new

C# поддерживает одномерные, многомерные и «зубчатые» массивы (массив содержащий другие массивы в качестве своих элементов).

 

Индексаторы

Индексаторы позволяют индексировать элементы экземпляры класса или структуры точно так же, как и массивы. Индексаторы напоминают свойства за исключением того, что их методы доступа принимают параметры (чаще всего это индекс элемента).
Примечание: CollectionBase является классом библиотеки, который используется для создания коллекций. List является защищенным членом CollectionBase, который хранит коллекцию элементов в виде списка.

 

Упаковка (boxing) и распаковка(unboxing)

Идея упаковки — одно из новшеств в C#. Как уже упоминалось выше, все типы данных, встроенные или определенные пользователем, являются производными от базового класса Object из пространства имен System. Таким образом, упаковка втроенного типа в Object называется боксинг(boxing), в то время как обратный процесс (распаковка) называется анбоксинг(unboxing).

Упаковка представляет собой процесс преобразования типа значения в тип object. Когда тип значения упаковывается средой .Net, она создает оболочку (box) для значения внутри объекта типа Object и сохраняет ее в куче. Операция распаковки извлекает тип значения из объекта. Упаковка является неявной; распаковка является явной (распаковка происходит когда объект, содержащий box, преобразуют обратно к своему первоначальному типу).

Параметры функции

В C# параметры функций бывают трех типов:

  • Переданные в функцию по значению/Входные параметры
  • Переданные в функцию по ссылке/Входные-выходные параметры
  • Выходные параметры

Если у вас есть представление о COM-интерфейсах и типах их параметров, типы параметров в C# покажутся вам знакомым.

Параметры, переданные в функцию по значению/Входные параметры

Параметры этого типа аналогичны передаче параметро по значению в C++. Значение переданного параметра копируется в локальную одноименную переменную, которая и исполльзуется внутри функции. Изменение значения такого параметра внутри функции никак не влияет на значение этого параметра вне функции.

 

Переданные в функцию по ссылке/Входные-выходные параметры

Переданные по ссылке параметры в C++ передаются либо через указатели или используя оператор ссылки &. В C# ссылочные параметры дают меньше шансов допустить ошибку. Ссылочные параметры также называются входными-выходными(In-Out) параметрами, потому, что вы передаете ссылку на адрес значения переменной в «куче», так что вы можете передать с помощью этой ссылки входное значение и получить испольжуя то же значение результат выполнения этой функции.

Вы не можете передать не инициализированную ссылку в качестве параметра функции. C# использует ключевое слово ref для ссылочных параметров. Вы также должны использовать ключевое слово ref с аргументом функции при передаче его в функцию требующую ссылочный параметр.
Пример:

 

 

Выходные параметры

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

 

Переменное число параметров и массивы в качестве параметров

Массивы в C# передаются в функцию используя ключевое слово params. Параметр типа массива всегда должен быть крайним правым аргументом функции. Только один параметр может иметь тип массива. Вы можете передать любое количество элементов в качестве аргумента типа этого массива.

Примечание: Это единственный способ в C# для создания опциональных (необязательных) параметров функции, а также для создания функций с переменным числом параметров.

 

Операторы

Операторы в C# очень похожи на операторы в C++ также, как и выражения. Тем не менее, в C# были добавлены некоторые новые и полезные операторы. Основные из них описаны ниже.

Оператор is

Оператор is принимает два операнда, возвращая в качестве результата значение типа bool. Оператор is используется для проверки имеют ли его операнды одинаковые типы (либо возможно преобразовать тип одного из операндов к типу другого операнда). Этот оператор может быть особенно полезен при использовании полиморфизма.

 

Оператор as

Оператор as проверят одинаковы ли типы операндов (либо есть возможность перобразования типа одного операнада в тип другого), точно так же как это делает оператор is, и, если это верно, то в качестве результата возвращает преобразованный или упакованный объект (если операнд может быть упакован в целевой тип, см. упаковка/распаковка). Если преобразование/упаковка не возможны, возвращается значение null.

 

Оператор foreach

Оператор foreach используется для перебора элементов коллекций, таких как массивы и т.д.

 

Оператор lock

Оператор lock гарантирует, что фрагмент кода, защищенный блокировкой для данного объекта, будет использоваться только в потоке, получающем эту блокировку. А все остальные потоки блокируются до тех пор, пока блокировка не будет снята. Блокировка снимается по завершении защищаемого ею фрагмента кода.

Оператор checked/unchecked

Как известно, результаты некоторых видов арифметических вычислений могут превышать диапазон представления чисел для типа данных, используемого в вычислении. В этом случае происходит так называемое переполнение. В C# при переполнении в арифметических вычислениях по умолчанию генерируется исключение.
Для управления этим поведением в C# есть возможность указать, будет ли в коде сгенерировано исключение при переполнении, с помощью ключевых слов checked и unchecked. Так, если требуется указать, что выражение будет проверяться на переполнение, следует использовать ключевое слово checked, а если требуется проигнорировать переполнение — ключевое слово unchecked. В последнем случае результат усекается, чтобы не выйти за пределы диапазона представления чисел для целевого типа выражения.

 

Оператор Switch

Поведение оператора Switch в C# отличается от поведения оператора switch в C++.
В C# после выполнения оператора Switch, выполнение программы не может перейти к следующей метке case, который это может произойти в C++.
Например:

Результат в C++:

В C# вы получите ошибку времени компиляции:

Однако, если для нескольких меток case вам надо выполнить одинаковый код, вы можете сделать это аналогично тому, как вы делаете это в C++:
Вы можете также использовать константные переменные для меток case:
 

Делегаты

Делегаты позволяют сохранить сслыку на функцию в переменной. В C++ аналогично организованно использование и хранение указателей на функции.

Делегаты объявляются с помощью ключевого слова delegate. Пример:

 

Наследование и полиморфизм

В C# допускается только одиночное наследование. Аналог множественного наследование из C++ может быть реализован с помощью интерфейсов.

 

Виртуальные функции

Виртуальные функции реализуют концепции полиморфизма же в C# аналогично C++, за исключением того, вы должны использовать ключевое слово override в сигнатуре реализации виртуальной функции в дочернем классе. Родительский класс, так же как в C++, использует ключевое слово virtual. Каждый класс, который переопределяет виртуальный метод должен использовать ключевое слово override.

 

Скрытие методов родительского класса с помощью ключевого слова «new»

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

Посмотрите, как при использовании полиморфизма метод Draw класса Rectangle не принимается в качестве полиморфной формы метода Draw класса Shape, вместо этого используется другой метод. Для того, чтобы избежать конфликта имен между метода в родительском и дочернем классах, мы использовали модификатор new.

Примечание: вы не можете использовать в том же классе две версии метода, одну с модификатором new, а другю с override или virtual. Как и в приведенном выше примере, нельзя добавить еще один вирутальный метод , названный Draw в класс Rectangle, или переопределить этот метод. Кроме того, в классе Square, нельзя переопределить виртуальный метод Draw класса Shape.

Вызов методов базового класса

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

 

Заключение

Эта статья является лишь кратким обзором особенностей языка С#. Хотя мы пытались обсудить в ней почти все основные концепции C#, тем не менее, многое осталось незатронутым. Следите за новыми статьями на CoderJob.Ru!

Источник: codeproject.com


Теги: