Введение в C#

Автор: admin | 12 Июнь 2008 – 23:02 -


Введение в C#

Последнее время С и С++ являются наиболее используемыми языками для разработки коммерческих и бизнес приложений. Эти языки устраивают многих разработчиков, но в действительности не обеспечивают должной продуктивности разработки. К примеру, процесс написания приложения на С++ зачастую занимает значительно больше времени, чем разработка эквивалентного приложения, скажем, на Visual Basic. Сейчас существуют языки, увеличивающие продуктивность разработки за счет потери в гибкости, которая так привычна и необходима программистам на С/С++. Подобные решения являются весьма неудобными для разработчиков и зачастую предлагают значительно меньшие возможности. Эти языки также не ориентированы на взаимодействие с появляющимися сегодня системами и очень часто они не соответствуют существующей практике программирования для Web. Многие разработчики хотели бы использовать современный язык, который позволял бы писать, читать и сопровождать программы с простотой Visual Basic и в то же время давал мощь и гибкость C++, обеспечивал доступ ко всем функциональным возможностям системы, взаимодействовал бы с существующими программами и легко работал с возникающими Web стандартами.

Учитывая все подобные пожелания, Microsoft разработала новый язык – C#. В него входит много полезных особенностей – простота, объектная ориентированность, типовая защищенность, “сборка мусора”, поддержка совместимости версий и многое другое. Данные возможности позволяют быстро и легко разрабатывать приложения, особенно COM+ приложения и Web сервисы. При создании C#, его авторы учитывали достижения многих других языков программирования: C++, C, Java, SmallTalk, Delphi, Visual Basic и т.д. Надо заметить что по причине того, что C# разрабатывался с чистого листа, у его авторов была возможность (которой они явно воспользовались), оставить в прошлом все неудобные и неприятные особенности (существующие, как правило, для обратной совместимости), любого из предшествующих ему языков. В результате получился действительно простой, удобный и современный язык, по мощности не уступающий С++, но существенно повышающий продуктивность разработок.

Web интеграция

Ввиду очень удобного объектно-ориентированного дизайна, C# является хорошим
выбором для быстрого конструирования различных компонентов – от высокоуровневой
бизнес логики до системных приложений, использующих низкоуровневый код. Также
следует отметить, что C# является и Web ориентированным -
используя простые встроенные конструкции языка ваши компоненты могут быть легко превращены в
Web сервисы, к которым можно будет обращаться из Internet посредством
любого языка на любой операционной системе. Дополнительные возможности
и преимущества перед другими языками приносит в C# использование передовых
Web технологий, таких как: XML (Extensible Markup Language) и SOAP
(Simple Object Access Protocol). Среда разработки Web сервисов позволяет
программисту смотреть на существующие сегодня Web приложения, как на родные
C# объекты, что дает возможность разработчикам соотнести имеющиеся Web
сервисы с их познаниями в объектно-ориентированном программировании.

Исключение ошибок

Очень часто можно проследить такую связь – чем более язык
защищен и устойчив к ошибкам, тем меньше производительность программ, написанных
на нем. К примеру рассмотрим две крайности – очевидно это Assembler и
Java. В первом случае вы можете добиться фантастической быстроты своей программы,
но вам придется очень долго заставлять ее работать правильно не
на вашем компьютере. В случае же с Java – вы получаете защищенность, независимость
от платформы, но, к сожалению, скорость вашей программы вряд ли
совместима со сложившимся представлением о скорости, например, какого-либо отдельного
клиентского приложения (конечно существуют оговорки – JIT компиляция и
прочее). Рассмотрим C++ с этой точки зрения – на мой взгляд соотношение в
скорости и защищенности близко к желаемому результату, но на основе собственного
опыта программирования я могу с уверенностью сказать, что практически
всегда лучше понести незначительную потерю в производительности программы
и приобрести такую удобную особенность, как “сборка мусора”, которая
не только освобождает вас от утомительной обязанности управлять памятью
вручную, но и помогает избежать вам многих потенциальных ошибок в
вашем приложении. В действительности скоро “сборка мусора”, да и любые доругие
шаги к устранению потенциальных ошибок стану отличительными чертами
современного языка. В C#, как в несомненно современном языке, также существуют
характерные особенности для обхода возможных ошибок. Например, помимо
упомянутой выше “сборки мусора”, там все переменные автоматически инициализируются
средой и обладают типовой защищенностью, что позволяет избежать неопределенных
ситуаций в случае, если программист забудет инициализировать переменную
в объекте или попытается произвести недопустимое преобразование типов.
Также в C# были предприняты меры для исключения ошибок при обновлении
программного обеспечения. Изменение кода, в такой ситуации, может непредсказуемо
изменить суть самой программы. Чтобы помочь разработчикам бороться с этой
проблемой C# включает в себя поддержку совместимости версий (vesioning).
В частности, в отличии от C++ и Java, если метод класса был изменен, это
должно быть специально оговорено. Это позволяет обойти ошибки в коде и
обеспечить гибкую совместимость версий. Также новой особенностью является
native поддержка интерфейсов и наследования интерфейсов. Данные возможности
позволяют разрабатывать сложные системы и развивать их со временем.

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

Переходя к более подробному знакомству с C#, традиционно рассмотрим программу “Hello, world”:

using System;
class Hello{
	static void Main() {
	Console.WriteLine("hello, world");
	}
}

Поместите эту программу в файл hello.cs и скомпилируйте ее командой

      	csc hello.cs

В результате вы получите файл hello.exe, запустив который, вы увидите надпись “hello, world”.

В C# была унифицирована система типов, теперь
вы можете рассматривать каждый тип как объект. Несмотря на то, используете
вы класс, структуру, массив или встроенный тип, вы можете обращаться к
нему как к объекту. Объекты собраны в пространства имен (namespaces),
которые позволяют программно обращаться к чему-либо. Это значит что вместо
списка включаемых файлов заголовков в своей программе вы должны написать
какие пространства имен, для доступа к объектам и классам внутри них,
вы хотите использовать. В C# выражение using позволяет вам не писать каждый
раз название пространства имен, когда вы используете класс из него. Например,
пространство имен System содержит несколько классов, в том числе и Console.
И вы можете писать либо название пространства имен перед каждым обращением
к классу, либо использовать using как это было показано в примере выше.

Статический метод Main – точка входа в программу. Этот метод обязательно должен быть статическим. Далее в нашем примере используется метод WriteLine из класса System.Console. Этот метод отправляет строку на стандартный вывод.

Простота использования

Важной и отличительной от С++ особенностью C# является его простота. К примеру, всегда ли вы помните, когда пишите на С++, где нужноиспользовать “->”, где “::”, а где “.”? Даже если нет, то компилятор всегда поправляет вас в случае ошибки. Это говорит лишь о том, что в действительности можно обойтись только одним оператором, а компилятор сам будет распознавать его значение. Так в C#, оператор”->” используется очень ограничено (в unsafe блоках, о которых речь пойдет ниже), оператор “::” вообще не существует. Практически всегда вы используете только оператор “.” и вам больше не нужно стоять перед выбором.

Еще
один пример. При написании программ на C/С++ вам приходилось думать не
только о типах данных, но и о их размере в конкретной реализации. В C#
все упрощено – теперь символ Unicode называется просто char (а не wchar_t,
как в С++) и 64-битное целое теперь – long (а не __int64). Также в C#
нет знаковых и беззнаковых символьных типов.

В C#, также как и в Visual Basic после каждого выражения case в блоке
switch подразумевается break. И более не будет происходить странных вещей
если вы забыли поставить этот break. Однако если вы действительно хотите
чтобы после одного выражения case программа перешла к следующему вы можете
переписать свою программу с использованием, например, оператора goto.

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

Многим программистам (на тот момент, наверное, будущим программистам)
было не так легко во время изучения C++ полностью освоиться с механизмом
ссылок и указателей. Многие путались в использовании операторов “*” и
“&”. В C# (кто-то сейчас вспомнит о Java) нет указателей. В действительности
нетривиальность указателей соответствовала их полезности. Например, порой,
трудно себе представить программирование без указателей на функции. В
соответствии с этим в C# присутствуют Delegates – как прямой аналог указателя
на функцию, но их отличает типовая защищенность, безопасность и полное
соответствие концепциям объектно-ориентированного программирования . Рассмотрим
пример их использования:

delegate void SimpleDelegate(); /* здесь мы объявляем тип Delegate -
			        принимаемые значения и возвращаемый тип */
class Test {
	static void F() {
		System.Console.WriteLine("Test.F");
	}
	static void Main() {
		SimpleDelegate d = new SimpleDelegate(F); /* создание объекта -
							  Delegate */
		d(); // Запуск Delegate
	}
}

Delegates это объекты, производные от общего базового объекта System.Delegate. Этот тип являет собой некую сущность, которую можно вызывать. В случае с экземпляром объекта – эта сущность состоит из экземпляра и его метода, в случае статического метода – из класса и статического метода этого класса. Именно благодаря этому не нарушатся концепции объектно-ориентированного программирования, а именно не используются методы объекта в отрыве от самого объекта.

Типовая защищенность

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

В C# вы не можете создать ссылку на произвольную область памяти. Все приведения типов должны быть безопасными. К примеру, вы не можете использовать приведение между reference (обращение по указателю на область памяти) и value (обращение к значению) типами. “Сбор мусора” обеспечит отсутствие в вашем коде болтающихся впустую ссылок.

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

Вообще, типы данных, присутствующие в C#, отличаются от типов в C++. Так
тип char тут 16-битный, а весьма полезные типы string и decimal являются
встроенными. Но куда большие отличия мы можем увидеть при рассмотрении
массивов. В C# могут быть многомерные массивы (multidimentional) и неровные
(или неуточненные – jagged – массивы массивов):

int[ ] intArray;		// Просто массив
int[ , , ] intArray;		// Трехмерный массив
int[ ][ ] intArray;		// неровный массив массивов
int[ ][ , , ][ , ] intArray;	/* Одномерный массив трехмерных массивов
				двумерных массивов :)  */

В принципе, использование массивов ничего нового из себя не представляет, но было бы полезно рассмотреть пример инициализации неровного массива:

int[][] intArray = new int[][] {
new int[] {2,3,4}, new int[] {5,6,7}
};

В C# появился оператор циклов foreach – перебор всех элементов “списка”. Его использование зависит от типов объектов, к которым он применяется, по причине того, что понятие “списка” может быть определено по разному. Проиллюстрируем его действие на примере:

int[] intArray = {2, 4, 6, 8, 10, -2, -3, -4, 8};

foreach (int i in intArray)	{
	System.Console.WriteLine(i);   // Вывод элементов массива по порядку
}

Удобство и современность C#

Хотелось бы подчеркнуть современное удобство
C#. Когда вы начнете работу с C#, а, надеюсь, это произойдет как можно скорее,
вы увидите, что довольно большое значение в нем имеют пространства имен.
Уже сейчас, на основе первого примера, вы можете судить об этом – ведь
все файлы заголовков заменены именно пространством имен. Так в C#, помимо
просто выражения using, предоставляется еще одна очень удобная возможность
- использование дополнительного имени (alias) пространства имен или класса.
Следующие примеры продемонстрируют это:

namespace NS3 { /* предположим, что у нас имеется вложенное пространство имен
		NS1.NS2, в котором находится ClassA */
	using A = NS1.NS2.ClassA; // Определяем дополнительное имя для класса
	class ClassB: A {} // Используем его
}

namespace NS3 { // или на уровне пространств имен
	using C = NS1.NS2;  // Определяем дополнительное имя для пространства имен
	class ClassB: C.ClassA {} // Используем его
}

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

<Код из первого файла DESIGNTIMESP=10915>

using System;
namespace DotSiteRes {
	public class HelloWorld {
		[conditional("DEBUG")] /* последующий метод будет выполняться
					только в случае определения DEBUG */
		public static void SayHi() {
			Console.WriteLine("Hello, World!");
			return;
		}
		...
	}
}

<Код из второго файла DESIGNTIMESP=10916>

using System;
using DotSiteRes;

#define DEBUG

class CallingDotSiteRes {
	public static void Main(string[] args) {
		HelloWorld.SayHi();
		return;
	}
}

В данном случае будет выведена строка “Hello,
world”. Если бы DEBUG не было определено, ничего бы не произошло. Не менее
полезное использование атрибутов будет продемонстрировано далее.

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

using System;
[AttributeUsage(AttributeTargets.All)] 

	/* Здесь уже пример использования аттрибутов - с их помощью мы говорим
	где может применяться наш атрибут-класс, определяемый ниже */

public class HelpAttribute: Attribute {

	/*аттрибут-класс - наследник класса System.Attribute. Необходимо
	заметить, что в HelpAttribute, Help является непосредственным именем
	аттрибут-класса, а Attribute - суффиксом. При использовании
	аттрибут-класcа HelpAttribute вы сможете обращаться к нему коротко -
	просто Help. */

      public HelpAttribute(string url) {
            this.url = url;
      }
      public string Topic = null;
      private string url;
      public string Url {
            get { return url; }
      }
}

[Help("http://www.mycompany.com/:/Class1.htm")] /* Применение нашего аттрибута
						к новому классу	*/
public class Class1 {

      [Help("http://www.mycompany.com/:/Class1.htm", Topic = "F")]
			/* Применение нашего аттрибута к методу */

      public void F() {}
}

class Test { // Класс, проверяющий аттрибуты
      static void Main() {
            Type type = typeof(Class1);
            object[] arr = type.GetCustomAttributes(typeof(HelpAttribute));
            /* прочтение аттрибутов класса Class1 */
            if (arr.Length == 0)
                  Console.WriteLine("Class1 has no Help attribute.");
            else {
                  HelpAttribute ha = (HelpAttribute) arr[0];
                  // Вывод аттрибутов
                  Console.WriteLine("Url = {0}, Topic = {1}", ha.Url, ha.Topic);
            }
      }
}

Дополнительные возможности

Реальный опыт разработки говорит нам о том, что некоторым программам и по сей день требуется native код, либо из соображений производительности, либо для взаимодействия с существующими API. Эта причина может заставить разработчиков использовать С++ даже когда они предпочли бы более продуктивную среду разработки. В С# для решения этой проблемы были приняты несколько решений: включена native поддержка COM-технологии и WinAPI, допускается ограниченно использовать native указатели. Разработчику больше не нужно точно реализовывать IUnknown и другие COM интерфейсы. Теперь эти особенности являются встроенными. Также C# программы могут органично использовать существующие COM объекты независимо от того, на каком языке они были написаны. Для тех разработчиков которым это необходимо, в C# была включена специальная особенность, которая позволяет программе обращаться к любому существующему native API. Внутри специально помеченного блока (unsafe) программисту позволяется использовать указатели и традиционные особенности С/С++, такие как, управление памятью вручную и арифметика указателей. Этот большой плюс отличает C# от других сред разработки. Вместо того, чтобы отказаться от уже существующего С/С++ кода, вы можете разрабатывать C# приложения, используя его. Ниже демонстрируется использование unsafe блоков:

struct Point{
      public int x;
      public int y;
      public override string ToString() {
      return "(" + x + "," + y + ")";
      }
}

class Test {
      unsafe static void Main() {
            Point point;
            Point* p =
            &point;p->x =
            10;p->y =
            20;Console.WriteLine(p->ToString());
      }
}

Как вы увидели, внутри unsafe блоков, как и в C++, возможно использование указателей. Также допускается и использование оператора”->”, который может быть заменен “(*p).”.

Заключение

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

31 октября этого года C# был стандартизован. Сейчас доступна его спецификация на английском языке, вы можете найти ее на сайте Microsoft. Там же вы можете скачать Microsoft Visual Studio .NET beta 1 и уже сегодня начать работу с C# и Microsoft .NET framework.


Tags: , , , , , , , , , ,
Находится в Введение в C# | No Comments »

Ответить

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


C# — язык программирования, сочетающий объектно-ориентированные и аспектно-ориентированные концепции. Разработан в 1998—2001 годах группой инженеров под руководством Андерса Хейлсберга в компании Microsoft как основной язык разработки приложений для платформы Microsoft .NET. Компилятор с C# входит в стандартную установку самой .NET, поэтому программы на нём можно создавать и компилировать даже без инструментальных средств вроде Visual Studio. дешевые рабочие перчатки . Service Desk: ремонт компьютеров жулебино. C# относится к семье языков с C-подобным синтаксисом, из них его синтаксис наиболее близок к С++ и Java. Язык имеет строгую статическую типизацию, поддерживает полиморфизм, перегрузку операторов, указатели на функции-члены классов, атрибуты, события, свойства, исключения, комментарии в формате XML. Переняв многое от своих предшественников — языков С++, Java, Delphi, Модула и Smalltalk — С#, опираясь на практику их использования, исключает некоторые модели, зарекомендовавшие себя как проблематичные при разработке программных систем: так, C# не поддерживает множественное наследование классов (в отличие от C++).