Параметры компилятора C#, которые определяют входные данные
Следующие параметры управляют входными данными компилятора. Новый синтаксис MSBuild выделен полужирным шрифтом. Для старого синтаксиса csc.exe используется формат code style
.
- References /
-reference
или-references
: создание ссылки на метаданные из указанного файла или файлов сборки. - AddModules /
-addmodule
: добавление модуля (созданного с помощьюtarget:module
для этой сборки). - EmbedInteropTypes /
-link
: встраивание метаданных из указанных файлов сборки взаимодействия.
Ссылки
Параметр Reference указывает компилятору импортировать сведения типа public из указанного файла в текущий проект. Это позволяет ссылаться на метаданные из указанных файлов сборки.
<Reference Include="filename" />
filename
— это имя файла, который содержит манифест сборки. Чтобы импортировать данные из нескольких файлов, включите отдельный элемент Reference для каждого файла. Псевдоним можно определить как дочерний элемент элемента Reference:
<Reference Include="filename.dll">
<Aliases>LS</Aliases>
</Reference>
В предыдущем примере LS
— это допустимый идентификатор C# для представления корневого пространства имен, которое будет содержать все пространства имен в сборке filename.dll. Импортируемые файлы должны содержать манифест. Для указания каталога, в котором находятся одна или несколько ссылок на сборки, используйте AdditionalLibPaths. В разделе с описанием AdditionalLibPaths также рассматриваются каталоги, в которых компилятор ищет сборки. Чтобы компилятор мог распознавать тип в сборке (не в модуле), ему следует указать принудительно разрешать типы. Это можно сделать, определив экземпляр типа. Возможны и другие способы разрешения компилятором имен типов в сборке. Например, если тип наследуется от типа в сборке, его имя будет распознаваться компилятором. Иногда бывает необходимо сослаться на две различные версии одного компонента из одной сборки. Для этого используйте элемент Aliases в элементе References для каждого файла, чтобы различать два этих файла. Этот псевдоним используется в качестве квалификатора имени компонента и разрешается в компонент в одном из файлов.
Примечание.
В Visual Studio используйте команду Добавить ссылку. Для получения дополнительной информации см. Практическое руководство. Добавление и удаление ссылок с помощью диспетчера ссылок.
AddModules
Установка этого параметра приводит к добавлению модуля, созданного с помощью параметра <TargetType>module</TargetType>
для текущей компиляции:
<AddModule Include=file1 />
<AddModule Include=file2 />
Где file
, file2
— это выходные файлы, содержащие метаданные. В этот файл не может входить манифест сборки. Чтобы импортировать несколько файлов, разделите их имена запятыми или точками с запятой. Все модули, добавленные с помощью AddModules, во время выполнения должны находиться в том же каталоге, что и выходной файл. То есть во время компиляции можно указать модуль в любом каталоге, но во время выполнения он должен находиться в каталоге приложения. Если во время выполнения модуль отсутствует в каталоге приложения, возникнет исключение TypeLoadException. file
не может содержать сборку. Например, если выходной файл был создан с помощью параметра TargetTypemodule, для импорта его метаданных можно использовать AddModules.
Если выходной файл был создан с помощью параметра TargetType, отличающегося от module, для импорта его метаданных нельзя использовать AddModules, но можно использовать параметр References.
EmbedInteropTypes
Дает компилятору указание сделать всю информацию о типах COM из указанных сборок доступной компилируемому проекту.
<References>
<EmbedInteropTypes>file1;file2;file3</EmbedInteropTypes>
</References>
Где file1;file2;file3
находится список имен файлов сборки с запятой. Если имя файла содержит пробел, заключите его в кавычки. Параметр EmbedInteropTypes позволяет развернуть приложение, содержащее сведения о внедренном типе. После этого приложение может использовать типы из сборки среды выполнения, реализующей информацию о внедренных типах, без ссылки на эту сборку. Если опубликовано несколько версий сборки среды выполнения, приложение, содержащее сведения о внедренных типах, может работать с различными версиями без перекомпиляции. Пример см. в разделе Пошаговое руководство. Внедрение данных о типах из управляемых сборок.
Параметр EmbedInteropTypes особенно полезен при работе с COM-взаимодействием. COM-типы внедряются для того, чтобы приложению не требовалась основная сборка взаимодействия (PIA) на целевом компьютере. Параметр EmbedInteropTypes указывает компилятору внедрить сведения о COM-типах из указанной сборки взаимодействия в результирующий скомпилированный код. COM-тип определяется значением CLSID (GUID). Это позволяет запускать приложение на целевом компьютере, где установлены те же COM-типы с такими же значениями CLSID. В качестве примера можно привести приложения, автоматизирующие Microsoft Office. Поскольку в приложениях типа Office значение CLSID обычно не зависит от версии, ваше приложение сможет использовать COM-типы по ссылке до тех пора, пока на целевом компьютере установлена платформа .NET Framework 4 или более поздней версии, а приложение работает с методами, свойствами или событиями, включенными в эти COM-типы. Параметр EmbedInteropTypes внедряет только интерфейсы, структуры и делегаты. Внедрение COM-классов не поддерживается.
Примечание.
Если в коде создается экземпляр внедренного COM-типа, его следует создавать, используя соответствующий интерфейс. При попытке создать экземпляр внедренного COM-типа с помощью компонентного класса возникнет ошибка.
Как и параметр References компилятора, параметр EmbedInteropTypes компилятора использует файл ответов Csc.rsp, который ссылается на часто используемые сборки .NET. Если вы не хотите, чтобы компилятор использовал файл Csc.rsp, примените параметр NoConfig компилятора.
// The following code causes an error if ISampleInterface is an embedded interop type.
ISampleInterface<SampleType> sample;
Типы с универсальным параметром, тип которого внедрен из сборки взаимодействия, нельзя использовать, если он относится к внешней сборке. Это ограничение не относится к интерфейсам. Например, рассмотрим интерфейс Range, который определен в сборке Microsoft.Office.Interop.Excel. Если библиотека содержит внедренные типы взаимодействия из сборки Microsoft.Office.Interop.Excel и предоставляет метод, возвращающий универсальный тип с параметром, типом которого является интерфейс Range, этот метод должен возвращать универсальный интерфейс, как показано в следующем примере кода.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
public class Utility
{
// The following code causes an error when called by a client assembly.
public List<Range> GetRange1()
{
return null;
}
// The following code is valid for calls from a client assembly.
public IList<Range> GetRange2()
{
return null;
}
}
В следующем примере клиентский код может вызывать метод, возвращающий универсальный интерфейс IList без ошибок.
public class Client
{
public void Main()
{
Utility util = new Utility();
// The following code causes an error.
List<Range> rangeList1 = util.GetRange1();
// The following code is valid.
List<Range> rangeList2 = (List<Range>)util.GetRange2();
}
}