入力を指定する C# コンパイラ オプション

以下のオプションは、コンパイラの入力を制御します。 新しい MSBuild 構文は、太字で示されています。 以前の csc.exe 構文は、code style で示されています。

  • References / -reference-references: 指定されたアセンブリ ファイルからメタデータを参照します。
  • AddModules / -addmodule: (target:module で作成された) モジュールをこのアセンブリに追加します。
  • EmbedInteropTypes / -link: 指定された相互運用アセンブリ ファイルからメタデータを埋め込みます。

リファレンス

References オプションを指定すると、コンパイラは指定されたファイルの public 型の情報を現在のプロジェクトにインポートし、指定されたアセンブリ ファイルからメタデータを参照できるようにします。

<Reference Include="filename" />

filename は、アセンブリ マニフェストを含むファイルの名前です。 複数のファイルをインポートするには、ファイルごとに個別に Reference 要素を指定します。 Reference 要素の子要素として別名を定義できます。

<Reference Include="filename.dll">
  <Aliases>LS</Aliases>
</Reference>

上の例の LS は、アセンブリ filename.dll 内のすべての名前空間を格納するルート名前空間を表す有効な C# 識別子です。 インポートするファイルには、マニフェストが含まれている必要があります。 1 つまたは複数のアセンブリ参照が配置されているディレクトリを指定するには、AdditionalLibPaths を使用します。 AdditionalLibPaths のトピックでは、コンパイラがアセンブリを検索するディレクトリについても説明されています。 モジュールではなくアセンブリ内の型をコンパイラで認識するには、型の解決を強制する必要があります。そのためには、型のインスタンスを定義します。 アセンブリの型名を解決する方法は他にもあります。たとえば、アセンブリの型を継承すると、コンパイラで型名が認識されます。 1 つのアセンブリ内から、同じコンポーネントの 2 つの異なるバージョンを参照することが必要になる場合があります。 そのためには、ファイルごとに References 要素の Aliases 要素を使用して、2 つのファイルを区別します。 この別名は、コンポーネント名の修飾子として使われ、いずれかのファイルのコンポーネントに解決されます。

注意

Visual Studio では、 [参照の追加] コマンドを使用します。 詳細については、「方法: 参照マネージャーを使用して参照を追加または削除する」を参照してください。

AddModules

このオプションを使用すると、<TargetType>module</TargetType> スイッチで作成されたモジュールが現在のコンパイルに追加されます。

<AddModule Include=file1 />
<AddModule Include=file2 />

ここで、filefile2 はメタデータを含む出力ファイルです。 このファイルには、アセンブリ マニフェストを含めることができません。 複数のファイルをインポートするには、コンマかセミコロンでファイル名を区切ります。 AddModules で追加したモジュールはすべて、実行時に出力ファイルと同じディレクトリに置かれている必要があります。 つまり、コンパイル時にはあるゆるディレクトリのモジュールを指定できますが、そのモジュールは実行時にアプリケーション ディレクトリに置かれている必要があります。 実行時にモジュールがアプリケーション ディレクトリにない場合、TypeLoadException が生成されます。 file には、アセンブリを含めることができません。 たとえば、出力ファイルが moduleTargetType オプションで作成された場合、そのメタデータは AddModules でインポートできます。

出力ファイルが module 以外の TargetType オプションで作成された場合、そのメタデータは AddModules ではインポートできませんが、References オプションでインポートできます。

EmbedInteropTypes

指定したアセンブリ内の COM 型情報を、現在のコンパイル対象のプロジェクトで使用できるようにします。

<References>
  <EmbedInteropTypes>file1;file2;file3</EmbedInteropTypes>
</References>

ここで、file1;file2;file3 はアセンブリ ファイル名のセミコロン区切りのリストです。 ファイル名に空白が含まれている場合は、名前を二重引用符で囲みます。 EmbedInteropTypes オプションを使用すると、埋め込み型情報を含むアプリケーションを配置できます。 その後、このアプリケーションは、埋め込み型情報を実装する、ランタイム アセンブリ内の型を使用できます。その際、ランタイム アセンブリへの参照は必要ありません。 ランタイム アセンブリのさまざまなバージョンが公開されている場合、埋め込み型情報を含むアプリケーションは、再コンパイルする必要なく、各種バージョンで動作できます。 例については、「チュートリアル:マネージド アセンブリからの型の埋め込み」をご覧ください。

EmbedInteropTypes オプションの使用は、COM 相互運用を使用している場合に特に便利です。 COM 型を埋め込むことができるため、アプリケーションは、ターゲット コンピューター上にプライマリ相互運用機能アセンブリ (PIA) を必要としなくなります。 EmbedInteropTypes オプションを使用すると、コンパイラによって、COM 型情報は、参照先の相互運用アセンブリから結果としてコンパイルされるコードに埋め込まれます。 COM 型は、CLSID (GUID) 値によって識別されます。 その結果、同じ CLSID 値の同じ COM 型がインストールされているターゲット コンピューターでアプリケーションを実行できます。 Microsoft Office を自動化するアプリケーションが良い例です。 Office のようなアプリケーションは、通常、さまざまなバージョン間で同じ CLSID 値を保持するため、.NET Framework 4 以降がターゲット コンピューターにインストールされていて、参照先の COM 型に含まれているメソッド、プロパティ、またはイベントがアプリケーションで使用される限りは、そのアプリケーションで参照先の COM 型を使用できます。 EmbedInteropTypes オプションで埋め込まれるのは、インターフェイス、構造体、デリゲートのみです。 COM クラスの埋め込みはサポートされていません。

注意

コードで埋め込み COM 型のインスタンスを作成する際は、適切なインターフェイスを使用してインスタンスを作成する必要があります。 コクラスを使用して埋め込み COM 型のインスタンスを作成しようとすると、エラーが発生します。

References コンパイラ オプションと同様、EmbedInteropTypes コンパイラ オプションでは、使用頻度の高い .NET アセンブリを参照する Csc.rsp 応答ファイルを使用します。 コンパイラで Csc.rsp ファイルを使用しない場合は、NoConfig コンパイラ オプションを使用してください。

// The following code causes an error if ISampleInterface is an embedded interop type.
ISampleInterface<SampleType> sample;

型が相互運用アセンブリから埋め込まれているジェネリック パラメーターを含む型は、外部アセンブリからの型である場合に使用できません。 この制限は、インターフェイスには適用されません。 たとえば、Microsoft.Office.Interop.Excel アセンブリで定義されている Range インターフェイスについて考えます。 ライブラリによって 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();
    }
}