Эндрю Троелсен - ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
- Название:ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2007
- Город:Москва • Санкт-Петербург • Киев
- ISBN:ISBN 5-8459-1124-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Эндрю Троелсен - ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание краткое содержание
В этой книге содержится описание базовых принципов функционирования платформы .NET, системы типов .NET и различных инструментальных средств разработки, используемых при создании приложений .NET. Представлены базовые возможности языка программирования C# 2005, включая новые синтаксические конструкции, появившиеся с выходом .NET 2.0, а также синтаксис и семантика языка CIL. В книге рассматривается формат сборок .NET, библиотеки базовых классов .NET. файловый ввод-вывод, возможности удаленного доступа, конструкция приложений Windows Forms, доступ к базам данных с помощью ADO.NET, создание Web-приложений ASP.NET и Web-служб XML. Книга содержит множество примеров программного кода, призванного помочь читателю в освоении предлагаемого материала. Программный код примеров можно загрузить с Web-сайта издательства.
ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed {
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
}
}
Во-первых, обратите внимание на то, что файл *.il начинается с объявления всех внешних компоновочных блоков, на которые ссылается данный компоновочный блок. Здесь вы видите только одну директиву .assembly extern для одного обязательно присутствующего mscorlib.dll. Если бы ваша библиотека классов использовала типы из других внешних компоновочных блоков, вы бы обнаружили дополнительные директивы .assembly extern.
Далее следует формальное определение вашего компоновочного блока HelloProgram.exe, для которого указана версия 0.0.0.0, назначаемая по умолчанию (если вы не укажете иное значение с помощью атрибута [AssemblyVersion]). После этого приводятся другие описания компоновочного блока, для которых используются другие директивы CIL (такие, как .module, .imagebase и т.д.).
После указания ссылок на внешние компоновочные блоки и определения текущего компоновочного блока идет определение типа Program. Обратите внимание на то, что директива.class имеет несколько атрибутов (многие из которых необязательны), – например, атрибут extends, задающий базовый класс типа.
.class private auto ansi beforefieldinit Program extends[mscorlib]System.Object {…}
Большой кусок программного кода CIL соответствует конструктору класса, заданному по умолчанию, и методу Main(). Оба они определены (в частности) с помощью директивы .method. После определения этих членов с помощью подходящих директив и атрибутов они реализуются с помощью различных кодов операций.
Важно понять, что в CIL при взаимодействии с типами .NET (например, с System.Console) всегда необходимо использовать абсолютные имена типов. Более того, к абсолютному имени типа всегда должен добавляться (в квадратных скобках) префикс с понятным именем компоновочного блока, определяющего этот тип. Взгляните на CIL-реализацию Main().
.method private hidebysig static void Main(string[] args) cil managed {
.entrypoint
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Hello CIL code!"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: call string [mscorlib]System.Console::ReadLine()
IL_0011: pop
IL_0012: ret
}
Реализация конструктора, заданного по умолчанию, в терминах программного кода CIL включает еще одну относящуюся к загрузке инструкцию (ldarg.0). В данном случае значение загружается в стек не как пользовательская переменная, указанная нами, а как текущая объектная ссылка (подробности этого процесса будут описаны позже). Также обратите внимание на то, что конструктор, заданный по умолчанию, явно вызывает конструктор базового класса.
.method public hidebysig specialname rtspecialname instance void .ctor cil managed {
.maxstack 8
IL_0000: ldarg.0
IL_0001: callinstance void [mscorlib]System.Object::.ctor()
IL_0006: ret
}
Роль меток в программном коде CIL
Вы. конечно, заметили, что в каждой строке программного кода реализации содержится префикс в форме лексемы IL_XXX: (например, IL_0000: IL_0001: и т.д.). Эти лексемы называются метками кода, и они могут иметь любой вид, какой вы только пожелаете (лишь бы они не дублировались в пределах одного и того же контекста). При записи содержимого компоновочного блока в файл с помощью ildasm.exe автоматически генерируются метки кода, имеющие вид IL_XXX:. Но вы можете изменить их с тем, чтобы они стали более информативными.
.method private hidebysig static void Main(string[] args) cil managed {
.entrypoint
.maxstack 8
Nothing_1: nop
Load_String:ldstr "Hello CIL code!"
PrintToConsole:call void [mscorlib]System.Console::WriteLine(string)
Nothing_2:nop
WaitFor_KeyPress:call string [mscorlib] System.Console::ReadLine()
RemoveValueFromStack: pop
Leave_Functlon: ret
}
Суть в том, что большинство меток кода совсем необязательно. Единственным случаем, когда метки кода оказываются по-настоящему полезными (и обязательными), является случай, когда в программном коде CIL используются ветвления или циклические конструкции. Например, в нашем случае вы можете исключить метки вообще.
.method private hidebysig static void Main(string[] args) cil managed {
.entrypoint
.maxstack 8
nop
ldstr "Hello CIL code!"
call void [mscorlib]System.Console::WriteLine(string)
nop
call string [mscorlib]System.Console::ReadLine()
pop
ret
}
Взаимодействие с CIL: модификация файла *.il
Теперь, когда вы понимаете, как компонуется базовый файл CIL, давайте завершим наш эксперимент с челночной технологией разработки программ. С помощью изменения CIL-кода в файле *.il мы должны выполнить следующее.
• Добавить ссылку на компоновочный блок System.Windows.Forms.dll.
• Загрузить локальную строку в Main().
• Вызвать метод System.Windows.Forms.MessageBox.Show(), используя локальную строковую переменную в качестве его аргумента.
Первым шагом является добавление новой директивы.assembly (с атрибутом extern), которая укажет, что используется System.Windows.Forms.dll. Для этого просто добавьте в файл *.il следующую программную логику после ссылки на внешний компоновочный блок mscorlib.
.assembly extern System.Windows.Forms {
.publickeytoken = (B7 7A 5C 56 19 34 E0 89)
.ver 2:0:0:0
}
Значение, указанное директивой .ver. может у вас оказаться другим, поскольку оно зависит от версии платформы .NET, установленной на вашей машине. Здесь указано использование System.Windows.Forms.dll версии 2.0.0.0 с кодом открытого ключа В77А5С561934Е089. Если открыть GAC (см. главу 11) и найти там компоновочный блок System.Windows.Forms.dll, можно скопировать правильный номер версии и значение открытого ключа со страницы свойств этого компоновочного блока.
.method private hidebysig static void Main(string[] args) cil managed {
.entrypoint
.maxstack 8
// Задача: написать новый CIL-код.
}
Итак, целью является помещение новой строки в стек и вызов метода MessageBox.Show() (а не метода Console.WriteLine()). Напомним, что при указании имени внешнего типа следует использовать абсолютное имя типа (в совокупности с понятным именем компоновочного блока). С учетом этого обновите метод Main() так, как показано ниже.
.method private hidebysig static void Main(string[] args) cil managed {
.entrypoint
.maxstack 8
ldstr"CIL работает прекрасно!"
callvaluetype [System.Windows.Forms] System.Windows.Forms.DialogResult [System . Windows.Forms] System.Windows.Forms.MessageBox::Show(string)
pop
ret
}
В результате вы получите программный код CIL, соответствующий следующему определению класса C#.
public class Program {
static void Main(string[] args) {
System.Windows.Forms.MessageBox.Show("CIL работает прекрасно!");
}
}
Компиляция CIL-кода с помощью ilasm.exe
Интервал:
Закладка: