Управляемый модуль программа содержит только il код

Начиная изучать язык C# и .NEt Framework я ни как не мог понять, как же работает CLR. Я либо находил огромные статьи, которые не осилить за 1 вечер либо слишком краткое, скорее даже запутывающее описание процесса (как в книге Г. Шилдта).
Некоторое время назад я решил, что было бы неплохо собирать знания, полученные из книг, «фичи» и часто используемые приемы в одном месте. А то новая информация быстро оседает в голове, но также быстро забывается и спустя несколько недель приходится вновь рыться в сотнях и тысячах строк текста, чтобы найти ответ на вопрос.

Читая очередную книгу по программированию, я делал краткие пометки самого важного, что мне показалось. Иногда описывал некоторый процесс понятным мне языком с придуманным примером и т.д. Я не претендую на абсолютную правильность излагаемого материала. Это всего лишь мое понимание процесса, с моими примерами и информацией, которую я посчитал ключевой для понимания Проработав некоторый материал, я решил сохранить это для всех тех, кому это может быть полезно. А кто уже знаком — тот просто освежит это в памяти.

Самая ВАЖНАЯ часть .NET

Нужно отметить, что понятие «тип» это некоторое подобие класса в языке C#. Но т.к. .NET поддерживает не только C# но и другие языки, то используется понятие «тип», а не привычный «класс». Также данная статья предполагает, что читатель уже знаком с особенностями .Net и раскрывает особенности специфических вещей и процессов.

В качестве примера приведу текст программы, выводящий на экран возраст объекта:
исходный текст программы, чтобы было понятно:
using System;

namespace ConsoleApplication_Test_Csharp
public class SomeClass
int age;
public int GetAge()
age = 22;
return age;
>
>
public sealed class Program
<
public static void Main()
System. Console .Write( «My age is » );
SomeClass me = new SomeClass();
int myAge;
myAge = me.GetAge();
System. Console .WriteLine(myAge);
Console .ReadLine();
>

>
>

* This source code was highlighted with Source Code Highlighter .

И так приступим:

Что такое CLR?

CLR (Common language runtime) — общеязыковая исполняющая среда. Она обеспечивает интеграцию языков и позволяет объектам благодаря стандартному набору типов и метаданным), созданным на одном языке, быть «равноправными гражданами» кода, написанного на другом.

CLR

Другими словами CLR этот тот самый механизм, который позволяет программе выполняться в нужном нам порядке, вызывая функции, управляя данными. И все это для разных языков (c#, VisualBasic, Fortran). Да, CLR действительно управляет процессом выполнения команд (машинного кода, если хотите) и решает, какой кусок кода (функцию) от куда взять и куда подставить прямо в момент работы программы. Процесс компиляции представлен на рисунке:

Неделя 5: 1 Управояемые модули и IL код

IL

IL (Intermediate Language) — код на специальном языке, напоминающим ассемблер, но написанном для .NET. В него преобразуется код из других языков верхнего уровня (c#, VisualBasic). Вот тогда-то и пропадает зависимость от выбранного языка. Ведь все преобразуется в IL (правда тут есть оговорки соответствия общей языковой спецификации CLS, что не входит в рамки данной статьи)
Вот как он выглядит для функции SomeClass::GetAge()

Компилятор, помимо ассемблера IL создает полные метаданные.

Метаданные — набор из таблиц данных, описывающих то, что определено в модуле. Также есть таблицы, указывающие на что ссылается управляемый модуль (например, импортируемые типы и числа). Они расширяют возможности таких технологий как библиотеки типов и файлы языка описания интерфейсов (IDL). Метаданные всегда связаны с файлом с IL кодом, фактически они встроены в *.exe или *.dll.
Таким образом метаданные это таблицы, в которых есть поля, говорящие о том, что такой-то метод находится в таком-то файле и принадлежит такому-то типу(классу).
Вот как выглядят метаданные для моего примера (таблицы метаданных просто преобразованы в понятный вид с помощью дизассемблера ILdasm.exe. На самом деле это часть *.exe файла программы:

metadata

TypeDef — это запись, для каждого типа, определенного в модуле
К примеру TypeDef #1 описывает класс SomeClass и показывает поле Field #1 с именем Field Name: age, метод MethodName: GetAge и конструктор MethodName: .ctor. Запись TypeDef #2 описывает класс Program.

Разобравшись с основными понятиями, давайте посмотрим из чего же состоит тот самый управляемый модуль (или просто наш файл ConsoleApplication_Test_Csharp.exe, который выполняет вывод на экран возраста объекта):

Работа JIT

И так, что же происходит, когда запускается впервые программа?
Сперва происходит анализ заголовка, чтобы узнать какой процесс запустить (32 или 64 разрядный). Затем загружается выбранная версия файла MSCorEE.dll ( C:WindowsSystem32MSCorEE.dll для 32разрядных процессоров)
После чего вызывается метод, расположенный MSCorEE.dll, который и инициализирует CLR, сборки и точку входа функции Main() нашей программы.

static void Main()
System. Console .WriteLine( «Hello » );
System. Console .WriteLine( «Goodbye» );
>

* This source code was highlighted with Source Code Highlighter .

Для выполнения какого-либо метода, например System.Console.WriteLine(«Hello „), IL должен быть преобразован в машинные команды (те самые нули и единицы) Этим занимается Jiter или just-in-time compiler.

Читайте также:
Как запустить программу на компиляцию и выполнение

Сперва, перед выполнением Main() среда CLR находит все объявленные типы (например тип Console).
Затем определяет методы, объединяя их в записи внутри единой “структуры» (по одному методу определенному в типе Console).
Записи содержат адреса, по которым можно найти реализации методов (т.е. те преобразования, которые выполняет метод).

Jit

При первом обращение к функции WriteLine вызывается JiT-compiler.
JiTer ‘у известны вызываемый метод и тип, которым определен этот метод.
JiTer ищет в метаданных соответствующей сборки — реализацию кода метода (код реализации метода WriteLine(string str) ).
Затем, он проверяет и компилирует IL в машинный код (собственные команды), сохраняя его в динамической памяти.
После JIT Compiler возвращается к внутренней «структуре» данных типа (Console) и заменяет адрес вызываемого метода, на адрес блока памяти с исполняемыми процессорными командами.
После этого метод Main() обращается к методу WriteLine(string str) повторно. Т.к. код уже скомпилирован, обращение производится минуя JiT Compiler. Выполнив метод WriteLine(string str) управление возвращается методу Main().

Из описания следует, что «медленно» работает функция только в момент первого вызова, когда JIT переводит IL код в инструкции процессора. Во всех остальных случаях код уже находится в памяти и подставляется как оптимизированный для данного процессора. Однако если будет запущена еще одна программа в другом процессе, то Jiter будет вызван снова для того же метода. Для приложений выполняемых в х86 среде JIT генерируется 32-разрядные инструкции, в х64 или IA64 средах — соответственно 64-разрядные.

Оптимизация кода. Управляемый и неуправляемый код

IL может быть оптимизирован, т.е. из него будут удалены IL — команды NOP (пустая команда). Для этого при компиляции нужно добавить параметры

Debug версия собирается с параметрами: /optimize -, /debug: full
Release версия собирается с параметрами: /optimize +, /debug: pdbonly

Чем же отличается управляемый код от неуправляемого?

Неуправляемый код компилируется для конкретного процессора и при вызове просто исполняется.

В управляемой среде компиляция производится в 2 этапа:

1) компилятор переводит C# код в IL
2) для исполнения нужно перевести IL код в машинный код процессора, что требует доп. динамической памяти и времени (как раз та самая работа JIT).

Взаимодействие с неуправляемым кодом:

— управляемый код может вызывать направляемую функцию из DLL посредствам P/Invoke (например CreateSemaphore из Kernel32.dll).
— управляемый код может использовать существующий COM-компонент (сервер).
— неуправляемый код может использовать управляемый тип (сервер). Можно реализовать COM — компоненты в управляемой среде и тогда не нужно вести подсчет ссылок интерфейсов.

Параметр /clr позволяет скомпилировать Visual С++ код в управляемые IL методы (кроме когда, содержащего команды с ассемблерными вставками ( __asm ), переменное число аргументов или встроенные процедуры ( __enable, _RetrurAddress )). Если этого сделать не получится, то код скомпилируется в стандартные х86 команды. Данные в случае IL кода не являются управляемыми (метаданные не создаются) и не отслеживаются сборщиком мусора (это касается С++ кода).

Система типов

В дополнение хочу рассказать о системе типов CTS, принятой Microsoft.

CTS (Common Type System) — общая система типов в CLR (тип, по-видимому — это аналог класса C#). Это — стандарт, признанный ECMA который описывает определение типов и их поведение. Также определяет правила наследования, виртуальных методов, времени жизни объектов. После регистрации ECMA стандарт получил название CLI ( Common Language Infrastructure)

— CTS поддерживает только единичное наследование (в отличие от С++)
— Все типы наследуются от System.Object (Object — имя типа, корень все остальных типов, System — пространство имен)

По спецификации CTS любой тип содержит 0 или более членов.

Поле — переменная, часть состояния объекта. Идентифицируются по имени и типу.
Метод — функция, выполняющая действие над объектом. Имеет имя, сигнатуру(число параметров, последовательность, типы параметров, возвр. значение функции) и модификаторы.
Свойство — в реализации выглядит как метод (get/set) а для вызывающей стороны как поле ( = ). Свойства позволяют типу, в котором они реализованы, проверить входные параметры и состояние объекта.
Событие — обеспечивает механизм взаимного уведомления объектов.

class Program

static void Main()

ClassA A = new ClassA();
A.data = 10;
>
>

нет, так как поле объявлено с модификатором static
да
нет, так как класс ClassA не публичный
нет, так как в этом случае нужно было сделать и класс статическим

Работа какого оператора дает верный ответ при условии, что a,b – переменные типа int, имеющие ненулевое значение?

Читайте также:
Программа для настройки почты на Андроид

if (a*b <0)
Console.WriteLine(«Оба числа одинакового знака»);

if (!(a*b>=0))
Console.WriteLine(«Оба числа одинакового знака»);

if (a*b>0)
Console.WriteLine(«Числа имеют разный знак»);

Ни один оператор не выполнится.

В результате выполнения фрагмента программы:

на экран будет выведено:
коло кола-колокола
кл кла-клкла
около кола-колокола

В результате выполнения фрагмента программы:

string str=»около кола-колокола»;
str.Replace(«о»,»»);
Console.WriteLine(str);

на экран будет выведено:
коло кола-колокола
кл кла-клкла
около кола-колокола

Перегрузка методов означает, что эти методы.

имеют одинаковые имена и различные списки параметр
имеют одинаковые имена и одинаковые списки параметров
имеют разные имена
имеют одинаковые имена, но относятся к разным классам иерархии

Для чтения символов из файла используется метод ReadLine. Этот метод возвращает.

очередной символ или null, если больше символов нет
код символа или -1, если больше символов нет
код символа или 0, если больше символов нет
строку (из которой потом извлекаются символы) или null, если больше символов нет

Каким будет результат работы фрагмента программы?

100 70 40
70 40 10 -20
100 70 40 10
70 40 10

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

Верно ли утверждение: «Управляемый модуль(программа) содержит только IL-код»?

Если требуется использовать методы Sort, предоставляемые встроенными коллекциями, то.

если тип элемента – простой, то ничего дополнительно делать не надо, в противном случае необходимо определить метод CompareTo
тип элемента обязательно должен быть простым типом, в противном случае использовать метод нельзя
необходимо определить метод Equals
необходимо определить метод CompareTo

Как называется инфраструктура строгой типизации и проверки кода?

Когда для записи файла следует использовать объект FileStream вместо объекта StreamWriter?

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

Переводится ли программа в машинный код при компиляции в среде CLR .Net Framework?

Какое пространство имен нужно приложению для работы с файлами?

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

по крайней мере один из них инициализирует все поля
все они имеют различные списки параметров
по крайней мере один из них является конструктором по умолчанию
все они имеют различные имена

В результате выполнения фрагмента программы

на экран будет выведено:
ничего, т.к. фрагмент содержит ошибку
мир
ира

Точкой входа в программу C# является:

функция с именем Main
любая первая функция, объявленная в программе

Каким будет результат выполнения фрагмента программы?

Если файл с именем file.txt не существует, что происходит при попытке выполнения следующей программной строки?
FileStream input=new FileStream(”file.txt”,FileMode.Open)

появляется окно каталогов, в котором пользователь должен найти данный файл
создается и открывается новый файл с именем file.txt
генерируется исключение IOException
Файл решения имеет расширение:

Если файл с именем file.txt не существует, что происходит при попытке выполнения следующей программной строки?

FileStream input=new FileStream(”file.txt”,FileMode.Open)
создается и открывается новый файл с именем file.txt
генерируется исключение FileNotFoundException
генерируется исключение IOException
появляется окно каталогов, в котором пользователь должен найти данный файл

В результате выполнения фрагмента программы

string line=»кол около колокола»;
char[] a=;
Console.WriteLine(line.IndexOfAny(a));
на экран будет выведено:

Дан обобщенный список
List list = new List ;
Какой фрагмент выведет весь список на экран?

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

System.Collections;
System.Collections.Generic;
System.Generic
Подключать ничего не требуется

Каким будет результат работы фрагмента программы?

int x = 100;
do

Console.Write(» «, x);
x = x — 30;
>
while (x > 0);

100
тело цикла не выполнится ни разу
100 70 40 10
фрагмент кода содержит ошибку

В результате выполнения следующего фрагмента программы

Выведется сообщение “Массив заполнен“
произойдет ошибка компиляции из-за несоответствия типов в операторе присваивания
будет сгенерировано исключение IndexOutOfRangeException

Каким будет результат работы фрагмента программы?

for (int j=1; j

Console.Write(«j»);
>

тело цикла не выполнится ни разу
фрагмент кода содержит ошибку
jjjj
1234

Файл решения имеет расширение:

Массив объявлен следующим образом:

int[ , , ] a=new int[5,2,4];
Чему равно значение a.Length?

Метод Length при обращении к потоку FileStream определит.

значений некоторого типа в потоке
количество байт в потоке
количество бит в потоке

Пространство имен в .Net Framework:

объявляет имена программных объектов в программе
ограничивает область применения имен программных объектов

Для того, чтобы в Visual Studio запустить консольное приложение в режиме ожидания нажатия клавиши для закрытия окна, потребуется нажать:

Допустимо ли обращение к полю data из функции Main?

class ClassA

Читайте также:
Программы появляются на всех устройствах

int data;
>

class Program

static void Main()

ClassA A = new ClassA();
A.data = 10;
>
>

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

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

Работа каких операторов дает верный ответ?

if (x%2!=0) Console.WriteLine(«x четное»);
else Console.WriteLine(«x нечетное»);

if (x%2==0) Console.WriteLine(«x четное»);
else Console.WriteLine(«x нечетное»);

if (x/2==0)Console.WriteLine(«x четное»);
else Console.WriteLine(«x нечетное»);

if (x%2!=0) Console.WriteLine(«x нечетное»);
else Console.WriteLine(«x четное»);

Выберите верные утверждения

Объекты обобщенной коллекции типизированы
Объекты обобщенной коллекции не типизированы
Объекты не обобщенной коллекции типизированы
Объекты не обобщенной коллекции могут хранить данные различных типов

Какие из следующих элементов могут быть обобщенными?

Перечисления
Классы
Структуры
Перегруженные версии операций
Методы
Свойства

Если метод объявлен как виртуальный, то любой производный класс.

должен представить переопределенный вариант этого метода с такими же параметрами
может представить переопределенный вариант этого метода с такими же параметрами
должен представить переопределенный вариант этого метода с аналогичными или другими параметрами
может представить переопределенный вариант этого метода с аналогичными или другими параметрами

Тип String представляет собой

Ссылочный тип данных. Последовательность символов в кодировке ASCII
Ссылочный тип данных. Последовательность символов в кодировке Unicode
Тип значение. Последовательность символов в кодировке Unicode
Тип значение. Последовательность символов в кодировке ASCII

Чему будет равняться значение переменной res после выполнения фрагмента программы?

int a = 5, b = 2, res;
res = a / b;

1
2,5
фрагмент содержит ошибку
2

Для того чтобы некоторый язык программирования мог использовать возможности FCL (библиотеки классов платформы) необходимо, чтобы он:

удовлетворял спецификации CLS (общая языковая спецификация)
являлся высокоуровневым языком программирования

Массив объявлен следующим образом
int[] Array = new int[5];
Какой из следующих фрагментов программы будет правильно выводить элементы данного массива?

for (i = 0; i Console.WriteLine(Array[i]);

for (i = 1; i < 5; i++)
Console.WriteLine(Array[i]);

for (i = 1; i Console.WriteLine(Array[i]);

for (i = 0; i < 5; i++)
Console.WriteLine(Array[i]);

Обращение к конструктору StreamWriter(«t.txt», true) означает, что файл t.txt открывается.

для перезаписи
для дозаписи

Пусть определен следующий класс
static class ClassA

>
Но при попытке создать экземпляр класса выдается ошибка. Почему?

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

Какое из следующих высказываний справедливо?

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

Только перечисленные языки: С#, VB.NET, Managed C++, JScript .NET, PascalABC.NET ориентированы на разработку приложений в среде CLR?

Что будет выведено на экран в результате работы следующего программного фрагмента?

char a = ‘z’;
Console.WriteLine((int)a);

122 (код символа ‘z’)
ничего, так как фрагмент кода содержит ошибку
неопределенное число
символ ‘z’

Массив объявлен следующим образом:
int[,] A = new int[4, 5];
Какой метод возвращает количество столбцов данного массива?

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

Каким будет результат работы фрагмента программы?

int y = 100;
while (y < 0)

Console.Write(» «,y);
y = y — 30;
>

100 70 40 10
фрагмент кода содержит ошибку
100 70 40
тело цикла не выполнится ни разу

Индексатор это

Специализированное свойство для организации доступа к индексированным полям объекта
Номер элемента массива в классе
Любое свойство объекта, к которому можно обратиться по его порядковому номеру
Специализированное поле класса для указания номера, какого-нибудь объекта

В данном примере

BinaryReader binReader = new BinaryReader(File.Open(fileName, FileMode.Open));
открывается двоичный поток на основе.
символьного потока
байтового потока

Пусть класс classA имеет два поля (типа int) field1 и field2 и конструктор, который инициализирует эти поля. Класс classB унаследован от classA. Он имеет собственное поле field3. Как надо определить конструктор класса classB, чтобы он инициализировал все три поля?

classB (int c, int a, int b)
classA(a, b);
field3 = c;
>

classB (int c, int a, int b): base(a, b)
field3 = c;
>

classB (int c, int a, int b)
super(a, b);
field3 = c;
>

classB (int c, int a, int b)
base(a, b);
field3 = c;
>

Что будет выведено в результате выполнения следующей программы?

Dictionary numbers = new Dictionary();
numbers [ «1» ] = » One»; numbers [ «2» ] = » Two»; numbers [ «3» ] = » Three» ;
foreach (KeyValuePair pair in numbers) Console.WriteLine(«», pair);

Будет ошибка компиляции

Произвольный доступ к потоку FileStream осуществляется через метод

Вы можете обратится к нам напрямую, через:

Или через форму обратной связи на нашем сайте

Сертификат

  • Сертификат

Получите наши последние новости и специальные предложения

Источник: otvety-na-testy.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru