вторник, 24 августа 2010 г.

Обзор CTS и CLS

 
Назначение
CTS и CLS служат для обеспечения совместимости, возможности взаимодействия и интеграции различных языков.
Общая система типов CTS
Поскольку в среде .NET все языки рассматриваются как равные, класс, написанный на С#, должен быть эквивалентен классу, написанному на VВ.NET, а интерфейс, определенный в управляемом С++, должен быть полностью аналогичен интерфейсу, определенному в управляемом Коболе. Языки должны договориться о значениях этих концепций перед тем, как смогут взаимодействовать друг с другом. Чтобы воплотить в реальность языковую интеграцию, фирма Мiсrоsоft определила общую систему типов, которой должен придерживаться любой язык в .NET. Мы выделим общие типы, имеющие одинаковую концептуальную семантику в любом языке среды .NET. Microsoft .NET поддерживает богатый набор типов, но мы ограничим наше обсуждение самыми важными из них, в частности размерными типами, ссылочными типами, классами, интерфейсами и делегатами.

Структура базовых типов
CLR поддерживает две различных категории типов: размерные типы и ссылочные типы. Размерные типы (value types) представляют значения, расположенные в стеке. Они не могут быть пустыми(null) и обязаны содержать какие-то данные. Такие данные передаются в функцию по значению, т. е. перед выполнением функции создается копия этого значения. Из этого следует, что исходное значение не меняется, независимо от того, что происходит с его копией в процессе вызова функции. Общая структура типов отражена на рис. 1.1. Заметьте, что все типы наследуются от одного типа Type.
clip_image002


Рис. 1.1. Структура базовых типов .NET

Размерные типы
Переменные размерного типа содержат само значение, а не ссылку на него.
Размерные типы включают примитивы, структуры и перечисления. Примеры приведены в следующем листинге С#:
int i; // примитив
struct Point { int х, у } // структура
enum State { Off=1, Оn=2 } // перечисление
Можно также создать размерный тип, породив производный класс от System.ValueTyре. Также необходимо отметить, что такой размерный тип является изолированным (sealed), т. е. если вы создали производный класс от System.ValueТype, никто другой уже не сможет создать класс, производный от вашего класса.

Ссылочные типы
Хотя ссылочные типы требуют значительных ресурсов памяти, ссылочный тип предоставляет преимущества по сравнению с размерным. Ссылочные типы (reference types) (в том числе объекты, интерфейсы и указатели) называются так, потому что содержат ссылки на объекты, расположенные в куче, и могут иметь пустое значение (null). Эти типы передаются по ссылке, т.е. когда вы передаете такай объект в функцию, передается адрес или указатель на объект, а не копия объекта, как в случае размерного типа. Поскольку передается ссылка, вызывающая сторона увидит, что вызванная функция сделала с вашим объектом. Первое преимущества состоит в там, что ссылочный тип может использоваться как выходной параметр, а второе - в том, что не тратятся лишние ресурсы, т. к. не создается копия объекта. Если ваш объект велик (занимает большой объем памяти), ссылочные типы являются лучшим выбором. В .NET один из недостатков ссылочного типа заключается в том, что память для него выделяется в управляемой куче, поэтому требуется больше тактов процессора, т. к. CLR должна управлять и осуществлять сборку мусора для этого объекта.
Ссылочные типы включают классы, интерфейсы, массивы и делегаты; их при меры показаны в следующем листинге на С#:
class Саr{…} // класс
interface ISteering{…} // интерфейс
int[] а = new int[5]; // массив
delegate void Process(…); // делегат
Упаковка и распаковка объектов
Поддержка размерных типов включена в Мiсrоsоft .NET в целях повышения производительности, однако все в .NET в конечном счете является объектом. На самом деле все примитивные типы имеют соответствующие классы в .NET Framework. Например, int представляет собой псевдоним System.Int32, а System.Int32 оказывается производным от System.ValueType, т. е. это размерный тип. Размерные типы по умолчанию располагаются в стеке, но они всегда могут быть преобразованы в ссылочный тип, располагающийся в куче, и эта операция называется упаковкой (boxing). Следующий фрагмент кода показывает, как упаковать копию значения переменной i:
int i = 1; //i – размерный тип
object Ьох = i; //box – ссылочный тип
Когда мы упаковываем значение, то получаем объект, для которого можно вызывать методы, свойства и события. Например, преобразовав целое в объект, как показано в этом фрагменте кода, вы можете вызывать методы, определенные в System.Object, в том числе ToString(), Equals() и т. д.
Операцией, обратной упаковке, естественно, является распаковка (unboxing), которая представляет собой преобразование объекта ссылочного типа, расположенного в куче, в эквивалентный ему размерный тип, как показано ниже:

int j = (int)box;

Классы, свойства, индексаторы
CLR предоставляет полноценную поддержку концепций объектно-ориентированного программирования (инкапсуляции, наследования и полиморфизма) и возможностей классов (методов, полей, статических членов, видимости, доступности, вложенных типов и т. п.). Кроме того, CLR поддерживает новые возможности, отсутствующие во многих традиционных объектно-ориентированных языках программирования, включая свойства, индексаторы и события.
Особенности классов:
  1. нет множественного наследования
  2. нет аналога шаблонов (в версии 1.1)
А сейчас кратко поговорим о свойствах и индексаторах.
Свойства похожи на поля (переменные-члены), за исключением того, что для них имеются методы-установщики (setters) и методы-получатели (getters), как показано ниже:
using System;
public class Car
{
private string make;
public string Make
{
get { return make; }
set { make = value; }
}
public static void Main()
{
Саr с = new Саr();
c.Make = “Acura”; // используется установщик
String s = c.Make; // используется получатель
Console.WriteLine(s);
}
}
Хотя, скорее всего, вы в первый раз видите такой синтаксис, этот пример прост и практически не требует пояснений, за исключением ключевого слова value. Это специальное ключевое слово, обозначающее первый и единственный аргумент метода-установщика.
Сходный со свойством синтаксически, индексатор аналогичен конструкции operator[] в С++, т. к. позволяет осуществлять доступ к содержимому объекта подобно обращению к массиву. Другими словами, индексатор позволяет обращаться к объекту так, как будто это обращение к массиву, что показано в следующем примере:
using System;
public class Саг
{
Саг()
{
wheels = new string[4];
}
private string[] wheels;
public string this[int index]
{
get { return wheels[ index]; }
set { wheels[index] = value; }
}
public static void Main()
{
Саr с = new Саr();
с[0] = “LеftWhееl”; // с[О] может быть как с правой, так \
// и с левой стороны присваивания
Console.WriteLine(c[O]);
}
}

Делегаты
Одним из наиболее мощных средств языка С является его поддержка указателей на функции. Указатели на функции позволяют создавать программное обеспечение с обработчиками, которые могут быть реализованы кем-то другим. Действительно, указатели на функции позволяют многим людям создавать расширяемое и настраиваемое программное обеспечение. Мiсrоsоft .NET поддерживает типизированную версию указателей на функции, называемых делегатами (delegates).
using System;
class TestDelegate
{
// 1. Определяем прототип для обратного вызова
delegate void MsgHandler(string strMsg);
// 2. Определяем метод обратного вызова
void OnMsg(string strMsg)
{
Console.WriteLine(strMsg);
}
public static void Main()
{
TestDelegate t = new TestDelegate();
// З. Привязка вашего метода обратного вызова
MsgHandler f = new MsgHandler(t.OnMsg);
// 4. Неявный вызов метода обратного вызова
f("Hello, Delegate. ");
}
}
Первое, что мы делаем, это определяем прототип функции обратного вызова, и здесь важным ключевым словом является delegate, которое сообщает компилятору, что вам требуется объектно-ориентированный указатель на функцию. При этом подспудно компилятор генерирует вложенный класс, MsgHandler, производный от System.MulticastDelegate. Широковещательный делегат поддерживает много приемников. Определив прототип, необходимо определить и реализовать метод с сигнатурой, соответствующей этому прототипу. Затем просто выполните привязку метода обратного вызова, передав функцию в конструктор делегата, как показано в этом листинге. И наконец, неявно вызовите ваш метод обратного вызова. Разобравшись с делегатами, заметим, что делегаты образуют основу событий.
Модификаторы доступа и атрибуты типов
К описанию переменной можно добавить следующие модификаторы, служашие для указания дополнительных параметров переменной (для C#):
Модификатор Описание
new переменная скрывает унаследованную переменную с той же сигнатурой.
public переменная доступна отовсюду как поле типа, к которому она принадлежит.
protected метод доступен из данного класса и из производного от него.
internal переменная доступна только из той же программы.
private переменная доступна только из типа, где она определена.
static статическое поле.
readonly после инициализации значение изменить нельзя.
const константа (толко примитивный тип).
protected internal переменная доступна из текущей программы или из производных типов.
Метод может принимат один или несколько следуюших модификаторов и атрибутов (для C#):
Модификатор Описание
new метод скрывает унаследованный метод с той же сигнатурой.
public метод доступен извне класса.
protected метод доступен из данного класса и из производного от него.
internal метод доступен только из той же программы.
private метод доступен только из класса, где он определён.
static метод не предназначен для работы с экземпляром данного класса.
virtual метод должен быть переопределён в производном классе.
abstract виртуальный метод, определяющий только сигнатуру (без реализации).
override метод переопределяет унаследованный виртуальный метод.
sealed метод перекрывает унаследованный виртуальный метод, но не может быть перекрыт классами, которые не являются производными от данного (использовать с override).
extern метод реализован вне программы.
Общая языковая спецификация CLS
Задача среды .NET состоит в такой поддержке языковой интеграции, чтобы программы можно было писать на любом языке, и при этом они могли бы взаимодействовать друг с другом, пользуясь всеми преимуществами наследования, полиморфизма, обработки исключений и другими возможностями. Однако языки созданы неодинаковыми, и разные языки поддерживают разные возможности. Например, С++ чувствителен к регистру, а VB.NET - нет. Чтобы составить из всего этого единое произведение, Мiсrоsоft опубликовала спецификацию Common Language Specification (CLS). В CLS определен набор базовых правил, обязательных для языковой интеграции.

Комментариев нет:

Отправить комментарий