C#-Compileroptionen, die Eingaben angeben

Mit den folgenden Optionen werden Compilereingaben gesteuert. Die neue MSBuild-Syntax wird fett formatiert dargestellt. Die ältere csc.exe-Syntax wird in code style dargestellt.

  • References / -reference oder -references: Verweist auf Metadaten aus den angegebenen Assemblydateien.
  • AddModules / -addmodule: Fügt dieser Assembly ein Modul hinzu (mit target:module erstellt).
  • EmbedInteropTypes / -link: Bettet Metadaten aus den angegebenen Interopassemblydateien ein.

References

Die Option References veranlasst den Compiler dazu, öffentliche Typinformationen in der angegebenen Datei in das aktuelle Projekt zu importieren, sodass die Verweismetadaten aus den angegebenen Assemblydateien aktiviert werden.

<Reference Include="filename" />

filename ist er Name einer Datei, die ein Assemblymanifest enthält. Fügen Sie ein separates Reference-Element für jede Datei ein, um mehrere Dateien zu importieren. Sie können einen Alias als untergeordnetes Element des Reference-Elements definieren:

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

Im vorherigen Beispiel ist LS der gültige C#-Bezeichner, der einen Stammnamespace darstellt, der alle Namespaces in der Assembly filename.dll enthält. Die von Ihnen importierten Dateien müssen ein Manifest enthalten. Verwenden Sie AdditionalLibPaths, um das Verzeichnis anzugeben, in dem sich mindestens einer Ihrer Assemblyverweise befindet. Im Thema AdditionalLibPaths werden auch die Verzeichnisse erläutert, in denen der Compiler nach Assemblys sucht. Damit der Compiler einen Typ in einer Assembly, und nicht in einem Modul, erkennen kann, muss die Auflösung des Typs durch die Definition einer Instanz des Typs erzwungen werden. Der Compiler verfügt über andere Möglichkeiten, Typnamen in einer Assembly aufzulösen. Beispielsweise wird beim Erben von einem Typ in einer Assembly der Typname vom Compiler erkannt werden. Manchmal ist es erforderlich, auf zwei verschiedene Versionen derselben Komponente aus einer Assembly heraus zu verweisen. Verwenden Sie dazu das Element Aliases für das Element References für jede Datei, um zwischen den beiden Dateien zu unterscheiden. Dieser Alias wird als Qualifizierer für den Namen der Komponente verwendet und wird für die Komponente in einer der Dateien aufgelöst.

Hinweis

Verwenden Sie in Visual Studio den Befehl Verweis hinzufügen. Weitere Informationen finden Sie unter Vorgehensweise: Hinzufügen und Entfernen von Verweisen mit dem Verweis-Manager.

AddModules

Mit dieser Option wird ein Modul hinzugefügt, das mit dem Schalter <TargetType>module</TargetType> in der aktuellen Kompilierung erstellt wurde:

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

Dabei sind file, file2 Ausgabedateien, die Metadaten enthalten. Die Datei darf kein Assemblymanifest enthalten. Trennen Sie die Dateinamen entweder mit einem Komma oder einem Semikolon, um mehr als eine Datei zu importieren. Alle Module, die mit AddModules hinzugefügt werden, müssen sich zur Laufzeit im gleichen Verzeichnis wie die Ausgabedatei befinden. Das bedeutet, dass Sie zur Kompilierzeit ein beliebiges Modul in einem Verzeichnis angeben können, sich das Modul aber zur Laufzeit im Anwendungsverzeichnis befinden muss. Wenn sich das Modul zur Laufzeit nicht im Anwendungsverzeichnis befindet, wird eine TypeLoadException ausgelöst. file darf keine Assembly enthalten. Wenn die Ausgabedatei z. B. mit der Option TargetType von module erstellt wurde, können ihre Metadaten mit AddModules importiert werden.

Wenn die Ausgabedatei mit einer anderen Option TargetType als module erstellt wurde, können ihre Metadaten nicht mit AddModules, aber mit der Option References importiert werden.

EmbedInteropTypes

Bewirkt, dass der Compiler dem Projekt, das Sie aktuell kompilieren, COM-Typinformationen in den angegebenen Assemblys bereitstellt.

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

Dabei ist file1;file2;file3 eine durch Semikolons getrennte Liste von Assemblydateinamen. Wenn der Dateiname ein Leerzeichen enthält, müssen Sie den Namen in Anführungszeichen einschließen. Die Option EmbedInteropTypes ermöglicht es Ihnen, eine Anwendung mit eingebetteten Typinformationen bereitzustellen. Die Anwendung kann dann Typen in einer Runtime-Assembly verwenden, die die eingebetteten Typinformationen implementieren, ohne dass ein Verweis auf die Runtime-Assembly erforderlich ist. Wenn verschiedene Versionen der Runtime-Assembly veröffentlicht werden, kann die Anwendung, die die eingebetteten Typinformationen enthält, mit den verschiedenen Versionen arbeiten, ohne neu kompiliert werden zu müssen. Ein Beispiel finden Sie unter Exemplarische Vorgehensweise: Einbetten von Typen aus verwalteten Assemblys.

Die Option EmbedInteropTypes ist besonders nützlich, wenn Sie COM-Interop verwenden. Sie können COM-Typen einbetten, sodass für Ihre Anwendung keine primäre Interopassembly (PIA) auf dem Zielcomputer mehr erforderlich ist. Die Option EmbedInteropTypes weist den Compiler an, die COM-Typinformationen aus der Interopassembly, auf die verwiesen wird, in den sich ergebenden kompilierten Code einzubetten. Der COM-Typ wird durch den CLSID (GUID)-Wert identifiziert. Dadurch kann Ihre Anwendung auf einem Zielcomputer ausgeführt werden, auf dem die gleichen COM-Typen mit den gleichen CLSID-Werten installiert sind. Anwendungen, die Microsoft Office automatisieren, sind ein gutes Beispiel. Da Anwendungen wie Office in der Regel den gleichen CLSID-Wert in den verschiedenen Versionen behalten, kann die Anwendung die COM-Typen, auf die verwiesen wird, verwenden, wenn .NET Framework 4 oder höher auf dem Zielcomputer installiert ist und die Anwendung Methoden, Eigenschaften oder Ereignisse verwendet, die in den COM-Typen, auf die verwiesen wird, enthalten sind. Die Option EmbedInteropTypes bettet nur Schnittstellen, Strukturen und Delegaten ein. Das Einbetten von COM-Klassen wird nicht unterstützt.

Hinweis

Wenn Sie eine Instanz eines eingebetteten COM-Typs in Ihrem Code erstellen, müssen Sie die Instanz mithilfe der entsprechenden Schnittstelle erstellen. Der Versuch, eine Instanz eines eingebetteten COM-Typs mit der Co-Klasse zu erstellen, verursacht einen Fehler.

Wie die Compileroption References verwendet auch die Compileroption EmbedInteropTypes die Antwortdatei „Csc.rsp“, die auf häufig verwendete .NET-Assemblys verweist. Verwenden Sie die Compileroption NoConfig, wenn Sie nicht möchten, dass der Compiler die Datei „Csc.rsp“ verwendet.

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

Typen, die über einen generischen Parameter verfügen, dessen Typ aus einer Interop-Assembly eingebettet wird, können nicht verwendet werden, wenn dieser Typ aus einer externen Assembly stammt. Diese Einschränkung gilt nicht für Schnittstellen. Nehmen Sie z.B. die Range Schnittstellen, die in der Microsoft.Office.Interop.Excel-Assembly definiert wird. Wenn eine Bibliothek Interop-Typen aus der Microsoft.Office.Interop.Excel-Assembly einbettet und eine Methode verfügbar macht, die einen generischen Typ zurückgibt, der einen Parameter mit dem Typ Range-Schnittstelle hat, muss diese Methode eine generische Schnittstelle zurückgeben, wie im folgenden Codebeispiel gezeigt.

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;
    }
}

Im folgenden Beispiel kann der Clientcode die Methode aufrufen, die die generische Schnittstelle IList ohne Fehler zurückgibt.

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();
    }
}