Параметры компилятора 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();
    }
}