Freigeben über


Beheben von Fehlern und Warnungen im Zusammenhang mit generischen Typparametern und generischen Typargumenten

In diesem Artikel werden die folgenden Compilerfehler behandelt:

  • CS0080: Einschränkungen sind für nicht generische Deklarationen nicht zulässig.
  • CS0081: Typparameterdeklaration muss ein Bezeichner sein, kein Typ.
  • CS0224: Eine Methode mit vararg kann nicht generisch sein, nicht in einem generischen Typ vorhanden sein oder einen Paramsparameter aufweisen.
  • CS0304: Es kann keine Instanz des Variablentyps erstellt werden, da sie nicht über die new() Einschränkung verfügt.
  • CS0305: Die Verwendung des generischen Typs erfordert N-Typargumente.
  • CS0306: Der Typ wird möglicherweise nicht als Typargument verwendet.
  • CS0307: Der Bezeichner ist keine generische Methode. Wenn Sie eine Ausdrucksliste vorgesehen haben, verwenden Sie Klammern um den Ausdruck.
  • CS0308: Die nicht generische Typ-oder-Methode kann nicht mit Typargumenten verwendet werden.
  • CS0310: Der Typ muss ein nicht abstrakter Typ mit einem öffentlichen parameterlosen Konstruktor sein, um ihn als Parameter im generischen Typ oder der generischen Methode zu verwenden.
  • CS0311: Der Typ kann nicht als Typparameter T im generischen Typ oder in der generischen Methode verwendet werden. Es gibt keine implizite Verweiskonvertierung von Typ1 in Typ2.
  • CS0312: Der Typ 'type1' kann nicht als Typparameter im generischen Typ oder der generischen Methode verwendet werden. Der nullwerte Typ 'type1' erfüllt die Einschränkung nicht.
  • CS0313: Der Typ "type1" kann nicht als Typparameter im generischen Typ oder der generischen Methode verwendet werden. Der nullwerte Typ 'type1' erfüllt die Einschränkung nicht. Nullable-Typen können keine Schnittstelleneinschränkungen erfüllen.
  • CS0314: Der Typ kann nicht als Typparameter im generischen Typ oder in der generischen Methode verwendet werden. Es gibt keine Konvertierung von Boxen oder Typparametern.
  • CS0315: Der Typ kann nicht als Typparameter T im generischen Typ oder der generischen Methode verwendet werden. Es gibt keine Boxumwandlung.
  • CS0401: Die new() Einschränkung muss die letzte angegebene Einschränkung sein.
  • CS0403: Null kann nicht in Typparameter konvertiert werden, da es sich um einen nicht nullablen Werttyp sein könnte. Erwägen Sie stattdessen die Verwendung default(T) .
  • CS0405: Doppelte Einschränkung für typparameter.
  • CS0412: Parameter: Ein Parameter, eine lokale Variable oder eine lokale Funktion kann nicht denselben Namen wie ein Methodentypparameter haben.
  • CS0413: Der Typparameter kann nicht mit dem as Operator verwendet werden, da er weder über eine Klassentypeinschränkung noch über eine Einschränkung verfügt class .
  • CS0417: Bezeichner: Beim Erstellen einer Instanz eines Variablentyps können keine Argumente bereitgestellt werden.
  • CS0449: Die Einschränkungen class, struct, unmanaged, notnull und default können nicht kombiniert oder dupliziert werden und müssen zuerst in der Einschränkungsliste angegeben werden.
  • CS0450: Typparameter: Ein Typparameter darf nicht sowohl eine Einschränkungsklasse als auch die class- oder struct-Einschränkung angeben.
  • CS0451: Die new() Einschränkung kann nicht mit der struct Einschränkung verwendet werden.
  • CS0454: Zirkeleinschränkungsabhängigkeit mit Typparameter 1 und Typparameter 2.
  • CS0455: Der Typparameter erbt widersprüchliche Einschränkungen.
  • CS0694: Der Typparameter hat denselben Namen wie der enthaltende Typ oder die Methode.
  • CS0695: T kann nicht beide Schnittstellen implementieren, da sie für einige Typenparameterersetzungen vereinheitlicht werden können.
  • CS0698: Ein generischer Typ kann nicht vom Typ abgeleitet werden, da es sich um eine Attributklasse handelt.
  • CS0702: Einschränkung darf keine spezielle Klasse sein.
  • CS0703: Inkonsistente Barrierefreiheit: Einschränkungstyp ist weniger zugänglich als Deklaration.
  • CS0706: Ungültiger Einschränkungstyp. Ein typ, der als Einschränkung verwendet wird, muss eine Schnittstelle, eine nicht versiegelte Klasse oder ein Typparameter sein.
  • CS0717: Statische Klasse: Statische Klassen können nicht als Einschränkungen verwendet werden.
  • CS1961: Ungültige Varianz: Der Typparameter muss für den Typ gültig sein.
  • CS7002: Unerwartete Verwendung eines generischen Namens.
  • CS8322: Argument mit dynamischem Typ kann nicht an generische lokale Funktion mit abgeleiteten Typargumenten übergeben werden.
  • CS9011: Schlüsselwort delegate kann nicht als Einschränkung verwendet werden. Haben Sie gemeint System.Delegate?
  • CS9012: Unerwartetes Schlüsselwort record. Haben Sie gemeint record struct oder record class?
  • CS9338: Inkonsistente Barrierefreiheit: Der Typ ist weniger barrierefrei als die Klasse.

Typparameterdeklaration und Benennung

Die folgenden Fehler beziehen sich auf die Deklarieren und Benennen von Typparametern in generischen Typen und Methoden:

  • CS0080: Einschränkungen sind für nicht generische Deklarationen nicht zulässig.
  • CS0081: Typparameterdeklaration muss ein Bezeichner sein, kein Typ.
  • CS0412: Parameter: Ein Parameter, eine lokale Variable oder eine lokale Funktion kann nicht denselben Namen wie ein Methodentypparameter haben.
  • CS0694: Der Typparameter hat denselben Namen wie der enthaltende Typ oder die Methode.
  • CS9012: Unerwartetes Schlüsselwort record. Haben Sie gemeint record struct oder record class?

Um diese Fehler zu beheben, stellen Sie sicher, dass Sie Typparameter mit gültigen Bezeichnern deklarieren, Einschränkungsklauseln nur auf generische Deklarationen anwenden und Namenskonflikte mit anderen Bezeichnern im Bereich vermeiden:

  • Entfernen Sie die Einschränkungsklausel aus nicht generischen Deklarationen (CS0080). Die where Klausel kann nur für generische Typen und Methoden verwendet werden, die Typparameter deklarieren, da Einschränkungen Anforderungen definieren, die Typargumente erfüllen müssen. Wenn Sie Einschränkungen anwenden müssen, fügen Sie dem Typ oder der Methodendeklaration zuerst Typparameter hinzu. Ändern Sie z. B. public class MyClass where MyClass : System.IDisposable in public class MyClass<T> where T : System.IDisposable.
  • Ersetzen Sie tatsächliche Typnamen durch Bezeichner in Typparameterdeklarationen (CS0081). Sie müssen Typparameter mithilfe von Bezeichnern (wie T, TKey oder TValue) anstelle von konkreten Typen (wie int oder string) deklarieren. Der Zweck eines Typparameters besteht darin, als Platzhalter zu dienen, den der Compiler durch tatsächliche Typen ersetzt, wenn der generische Typ oder die Methode verwendet wird. Ändern Sie z. B. public void F<int>() in public void F<T>().
  • Benennen Sie Typparameter, lokale Variablen oder Parameter um Namenskonflikte zu vermeiden (CS0412, CS0694). Typparameternamen dürfen keine Bezeichner im selben Bereich überdecken. Sie können nicht mit dem Namen des enthaltenen Datentyps oder der Methode übereinstimmen. Solche Konflikte erzeugen Mehrdeutigkeit darüber, auf welchen Bezeichner verwiesen wird. Wenn Sie z. B. über eine Methode public void F<T>()verfügen, können Sie keine lokale Variable double T innerhalb dieser Methode deklarieren, und Sie können einen Typparameter nicht so benennen wie der enthaltende Typ (class C<C>).
  • Verwenden Sie die richtige Datensatzdeklarationssyntax (CS9012). Beim Deklarieren eines Datensatztyps müssen Sie entweder record class oder record struct (oder nur record für einen Verweistyp) verwenden. Das record Schlüsselwort allein kann nicht an Positionen angezeigt werden, an denen der Compiler eine Typdeklarationssyntax erwartet. Wenn Sie z. B. einen Datensatztyp deklarieren möchten, schreiben Sie record class MyRecord oder record struct MyRecord und platzieren Sie nicht record, wo ein anderes Schlüsselwort erwartet wird.

Weitere Informationen finden Sie unter "Generic Type Parameters " und "Generics".

Deklaration von Einschränkungen und deren Anordnung

Die folgenden Fehler beziehen sich auf die Syntax und Sortierung von Einschränkungen für generische Typparameter:

  • CS0401: Die new() Einschränkung muss die letzte angegebene Einschränkung sein.
  • CS0449: Die classEinschränkungen , struct, , unmanagednotnullund default Einschränkungen können nicht kombiniert oder dupliziert werden und müssen zuerst in der Einschränkungsliste angegeben werden.
  • CS0450: Typparameter: Sowohl eine Einschränkungsklasse als auch die Einschränkung class oder struct kann nicht angegeben werden.
  • CS0451: Die new() Einschränkung kann nicht mit der struct Einschränkung verwendet werden.
  • CS9011: Schlüsselwort delegate kann nicht als Einschränkung verwendet werden. Haben Sie gemeint System.Delegate?

Einschränkungen für Typparameter müssen einer bestimmten Reihenfolge folgen: Primäre Einschränkungen (class, , struct, unmanaged, notnulloder default) kommen zuerst, gefolgt von Schnittstellen- oder Klasseneinschränkungen und schließlich der new() Konstruktoreinschränkung. Einige Einschränkungen schließen sich gegenseitig aus und können nicht kombiniert werden.

So beheben Sie diese Fehler:

  • Platzieren Sie die new() Einschränkung am Ende der Einschränkungsliste (CS0401). Die new() Einschränkung muss nach allen anderen Einschränkungen angezeigt werden. Ändern Sie z. B. where T : new(), IDisposable in where T : IDisposable, new().
  • Platzieren Sie primäre Einschränkungen zuerst, und kombinieren Sie keine sich gegenseitig ausschließenden Einschränkungen (CS0449). Sie können höchstens eines von class, struct, unmanaged, notnull oder default angeben, und dieses muss zuerst in der Einschränkungsliste stehen. Die class und struct Einschränkungen schließen sich gegenseitig aus, ebenso wie class und unmanaged. In einem nullablen Kontext class impliziert notnullbereits, sodass sie nicht kombiniert werden können.
  • Kombinieren Sie keine bestimmte Klasseneinschränkung mit struct (CS0450). Wenn ein Typparameter auf einen bestimmten Klassentyp beschränkt ist, handelt es sich implizit um einen Verweistyp, der der struct Einschränkung widerspricht. Entfernen Sie entweder die Klasseneinschränkung oder die struct Einschränkung.
  • Nicht kombinieren new() mit struct (CS0451). Alle Werttypen (Structs) haben implizit einen öffentlichen parameterlosen Konstruktor, sodass die new() Einschränkung redundant ist, wenn sie mit struct kombiniert wird. Entfernen Sie die Einschränkung new(), wenn Sie struct verwenden.
  • Ersetzen durch delegateSystem.Delegate in Einschränkungsklauseln (CS9011). Das delegate Schlüsselwort wird zum Deklarieren von Delegattypen und nicht als Einschränkung verwendet. Verwenden Sie System.Delegate den Einschränkungstyp, um einen Typparameter auf Stellvertretungstypen zu beschränken. Ändern Sie z. B. where T : delegate in where T : System.Delegate.

Das folgende Beispiel zeigt die richtige Reihenfolge der Einschränkung:

using System;

// Primary constraint first, then interface constraints, then new()
class C<T> where T : class, IDisposable, new() { }

// struct doesn't need new() - it's implicit
class D<T> where T : struct, IComparable { }

// Delegate constraint using System.Delegate
class E<T> where T : System.Delegate { }

Weitere Informationen finden Sie unter Einschränkungen für Typparameter (C#-Programmierhandbuch).

Typargumentanzahl und -verwendung

Die folgenden Fehler beziehen sich auf die Angabe der richtigen Anzahl und Typ von Typargumenten für generische Typen und Methoden:

  • CS0224: Eine Methode mit vararg kann nicht generisch sein, nicht in einem generischen Typ vorhanden sein oder einen Paramsparameter aufweisen.
  • CS0305: Die Verwendung des generischen Typs erfordert N-Typargumente.
  • CS0306: Der Typ wird möglicherweise nicht als Typargument verwendet.
  • CS0307: Der Bezeichner ist keine generische Methode. Wenn Sie eine Ausdrucksliste vorgesehen haben, verwenden Sie Klammern um den Ausdruck.
  • CS0308: Die nicht generische Typ-oder-Methode kann nicht mit Typargumenten verwendet werden.
  • CS7002: Unerwartete Verwendung eines generischen Namens.

Um diese Fehler zu beheben, stellen Sie sicher, dass Sie die genaue Anzahl von Typargumenten angeben, die von der generischen Deklaration benötigt werden. Verwenden Sie nur gültige Typen als Typargumente. Wenden Sie keine Typargumente auf nicht generische Konstrukte an:

  • Entfernen Sie generische Typparameter oder enthaltende generische Typdeklarationen aus den Methoden, die __arglist verwenden (CS0224). Das __arglist Schlüsselwort ist nicht mit Generischen kompatibel, da die Laufzeitmechanismen für die Behandlung von Variablenargumentlisten mit der Typersetzung in Konflikt stehen, die für generische Typparameter erforderlich ist. Diese Einschränkung gilt auch für das params Schlüsselwort, wenn sie in Kombination mit generischen Methoden oder Methoden in generischen Typen verwendet wird.
  • Geben Sie die genaue Anzahl von Typargumenten an, die in der generischen Typ- oder Methodendeklaration (CS0305) angegeben sind. Jeder in der Definition deklarierte generische Typparameter muss ein entsprechendes Typargument aufweisen, wenn der generische Typ instanziiert wird. Der Compiler muss wissen, welcher konkrete Typ für jeden Typparameter ersetzt werden soll. Wenn z. B. eine Klasse als class MyList<T> deklariert wird, müssen Sie genau ein Typargument angeben, wenn Sie sie verwenden, z. B. MyList<int> und nicht MyList<int, string>.
  • Verwenden Sie nur gültige Typen als Typargumente (CS0306). Zeigertypen, wie z. B. int* oder char*, können nicht als Typargumente verwendet werden, da generische Typen verwaltete Typen erfordern, die vom Garbage Collector nachverfolgt werden können, und Zeigertypen sind nicht verwaltet. Wenn Sie mit Zeigern in einem generischen Kontext arbeiten müssen, sollten Sie IntPtr verwenden oder den Code umstrukturieren, um zu vermeiden, dass Generika mit unsicherem Code gemischt werden.
  • Entfernen sie die Typargumentsyntax aus nicht generischen Konstrukten (CS0307, CS0308). Typargumente, die in spitzen Klammern eingeschlossen sind (z. B. <int>), können nur auf generische Typen und Methoden angewendet werden, die Typparameter deklarieren. Sie müssen entweder die Typargumente vollständig entfernen oder sicherstellen, dass Sie den Namespace importiert haben, der die generische Version des Typs enthält. Zum Beispiel erfordert IEnumerator<T> die using System.Collections.Generic;-Richtlinie, während IEnumerator in System.Collections ist.
  • Entfernen Sie Typparameter aus Deklarationen, die keine Generics (CS7002) unterstützen. Einige Konstrukte, z. B. Enumerationen, können nicht generisch sein. Wenn Sie einen generischen Container für Enumerationswerte benötigen, sollten Sie stattdessen eine generische Klasse oder Struktur verwenden.

Weitere Informationen finden Sie unter "Generic Type Parameters " und "Generics".

Konstruktoreinschränkungen

Die folgenden Fehler beziehen sich auf die new() Einschränkung für generische Typparameter:

  • CS0304: Es kann keine Instanz des Variablentyps erstellt werden, da sie nicht über die new() Einschränkung verfügt.
  • CS0310: Der Typ muss ein nicht abstrakter Typ mit einem öffentlichen parameterlosen Konstruktor sein, um ihn als Parameter im generischen Typ oder der generischen Methode zu verwenden.
  • CS0417: Bezeichner: Beim Erstellen einer Instanz eines Variablentyps können keine Argumente bereitgestellt werden.

Um diese Fehler zu beheben, fügen Sie die new() Einschränkung zu Typparametern hinzu, die instanziiert werden müssen, stellen Sie sicher, dass Typargumente öffentliche parameterlose Konstruktoren aufweisen, und vermeiden Sie das Übergeben von Argumenten beim Erstellen von Instanzen von Typparametern:

  • Fügen Sie die new() Einschränkung zur Typparameterdeklaration (CS0304) hinzu. Wenn Sie den new Operator verwenden, um eine Instanz eines Typparameters innerhalb eines generischen Typs oder einer generischen Methode zu erstellen, muss der Compiler in der Lage sein, sicherzustellen, dass jedes typargument, das zur Laufzeit bereitgestellt wird, über einen parameterlosen Konstruktor verfügt. Die new() Einschränkung bietet diese Garantie zur Kompilierungszeit, sodass der Compiler den entsprechenden Instanziierungscode generieren kann. Wenn Sie z. B. über class C<T> mit einem Mitglied T t = new T(); verfügen, müssen Sie die Deklaration in class C<T> where T : new() ändern.
  • Stellen Sie sicher, dass Typargumente, die mit new() eingeschränkten Typparametern verwendet werden, öffentliche parameterlose Konstruktoren (CS0310) aufweisen. Wenn ein generischer Typ oder eine Methode eine new() Einschränkung für einen Typparameter deklariert, muss jeder konkrete Typ, der als Typargument verwendet wird, nicht abstrakt sein und einen öffentlichen parameterlosen Konstruktor bereitstellen. Wenn ein Typ nur nicht öffentliche Konstruktoren (z. B. private-Konstruktoren) oder Konstruktoren mit Parametern enthält, kann er die new()-Einschränkung nicht erfüllen. Um diesen Fehler zu beheben, fügen Sie dem Typ entweder einen öffentlichen parameterlosen Konstruktor hinzu, oder verwenden Sie ein anderes Typargument, das bereits über eins verfügt.
  • Entfernen Von Konstruktorargumenten beim Instanziieren von Typparametern (CS0417). Die new() Einschränkung garantiert nur das Vorhandensein eines parameterlosen Konstruktors, sodass Sie keine Argumente new T(arguments) übergeben können, da der Compiler nicht überprüfen kann, ob ein Konstruktor mit diesen spezifischen Parametertypen für die Typen vorhanden ist, die ersetzt Twerden. Wenn Sie Instanzen mit bestimmten Argumenten erstellen müssen, sollten Sie die Verwendung von Factorymethoden, abstrakten Factorymustern oder spezifischen Basisklassen- oder Schnittstelleneinschränkungen in Betracht ziehen, die das benötigte Konstruktionsverhalten definieren.

Weitere Informationen finden Sie unter Einschränkungen für Typparameter und die new() Einschränkung.

Erfüllung von Einschränkungen und Konvertierungen

Die folgenden Fehler beziehen sich auf Typargumente, die die Einschränkungen generischer Typparameter nicht erfüllen:

  • CS0311: Der Typ kann nicht als Typparameter T im generischen Typ oder in der generischen Methode verwendet werden. Es gibt keine implizite Verweiskonvertierung.
  • CS0312: Der Typ kann nicht als Typparameter im generischen Typ oder der generischen Methode verwendet werden. Der nullable Typ erfüllt die Einschränkung nicht.
  • CS0313: Der Typ kann nicht als Typparameter im generischen Typ oder der generischen Methode verwendet werden. Der nullable Typ erfüllt die Einschränkung nicht. Nullable-Typen können keine Schnittstelleneinschränkungen erfüllen.
  • CS0314: Der Typ kann nicht als Typparameter in dem generischen Typ oder der generischen Methode verwendet werden. Es gibt keine Boxing-Konvertierung oder Konvertierung für Typparameter.
  • CS0315: Der Typ kann nicht als Typparameter T im generischen Typ oder der generischen Methode TypeorMethod<T>verwendet werden. Es gibt keine Boxumwandlung.

Um diese Fehler zu beheben, verwenden Sie Typargumente, die alle Einschränkungen durch geeignete Konvertierungen erfüllen, sicherstellen, dass abgeleitete Klassen Basisklasseneinschränkungen wiederholen und verstehen, dass nullfähige Werttypen spezielle Einschränkungsanforderungen haben:

  • Ändern Sie das Typargument in ein Argument, das über eine implizite Verweiskonvertierung in den Einschränkungstyp (CS0311) verfügt. Wenn ein Typparameter eine Einschränkung wie where T : BaseType hat, muss BaseType jedes Typargument durch eine implizite Verweiskonvertierung oder Identitätskonvertierung konvertierbar sein. Das Typargument muss BaseType selbst sein, sich von BaseType ableiten oder BaseType implementieren, wenn es sich um eine Schnittstelle handelt. Implizite numerische Konvertierungen (z. B. von short zu int) erfüllen keine generischen Typparametereinschränkungen, da es sich bei diesen Konvertierungen um Wertkonvertierungen handelt, nicht um Verweiskonvertierungen.
  • Wiederholen Sie die Typparametereinschränkungen der Basisklasse in einer abgeleiteten Klassendeklaration (CS0314). Wenn eine abgeleitete generische Klasse von einer generischen Basisklasse erbt, die Einschränkungen für die Typparameter aufweist, muss die abgeleitete Klasse dieselben Einschränkungen für die entsprechenden Typparameter deklarieren. Sie müssen diese Einschränkungen wiederholen, da der Compiler überprüfen muss, ob typargumente, die der abgeleiteten Klasse bereitgestellt werden, den Anforderungen der Basisklasse entsprechen. Wenn Sie beispielsweise eine Klasse public class A<T> where T : SomeClass haben, muss jede davon abgeleitete Klasse als public class B<T> : A<T> where T : SomeClass deklariert werden.
  • Verwenden Sie nicht nullable Werttypen, oder ändern Sie den Einschränkungstyp (CS0312, CS0313). Nullable-Werttypen (wie int?) unterscheiden sich von ihren zugrunde liegenden Werttypen und erfüllen nicht dieselben Einschränkungen. Es gibt keine implizite Konvertierung zwischen int? und int, und nullable Werttypen können Schnittstelleneinschränkungen nicht erfüllen, da der nullable Wrapper selbst die Schnittstelle nicht implementiert, obwohl der zugrunde liegende Werttyp dies tut. Um diese Fehler zu beheben, verwenden Sie entweder die nicht-nullbare Form des Werttyps als Typargument, oder passen Sie Ihre Einschränkung an, um object oder bei Bedarf einen nullfähigen Referenztyp zu akzeptieren.
  • Stellen Sie sicher, dass Typargumente Bezugstypen oder Klasseneinschränkungen erfüllen (CS0315). Wenn ein Typparameter auf einen Klassentyp (where T : SomeClass) beschränkt ist, können Sie keinen Werttyp (Struktur) als Typargument verwenden, da keine Boxing-Konvertierung vorhanden ist, die die Einschränkung erfüllt. Die Einschränkung erfordert einen Referenztyp, der eine Vererbungs- oder Implementierungsbeziehung zum Einschränkungstyp aufweist. Um diesen Fehler zu beheben, ändern Sie die Struktur entweder semantisch in eine Klasse, oder entfernen Sie die Klasseneinschränkung, wenn der generische Typ mit Werttypen arbeiten kann.

Weitere Informationen finden Sie unter Einschränkungen für Typparameter und implizite Konvertierungen.

Allgemeine Typverwendungseinschränkungen

Die folgenden Fehler beziehen sich auf Einschränkungen hinsichtlich der Verwendung generischer Typen:

  • CS0403: Null kann nicht in Typparameter konvertiert werden, da es sich um einen nicht nullablen Werttyp sein könnte. Erwägen Sie stattdessen die Verwendung default(T) .
  • CS0413: Der Typparameter kann nicht mit dem as Operator verwendet werden, da er weder über eine Klassentypeinschränkung noch über eine Einschränkung verfügt class .
  • CS0695: Der Typ kann nicht beide Schnittstellen implementieren, da sie sich für einige Typenparameterersetzungen vereinheitlichen könnten.
  • CS0698: Ein generischer Typ kann nicht vom Typ abgeleitet werden, da es sich um eine Attributklasse handelt.
  • CS8322: Argument mit dynamischem Typ kann nicht an generische lokale Funktion mit abgeleiteten Typargumenten übergeben werden.
  • CS9338: Inkonsistente Barrierefreiheit: Der Typ ist weniger barrierefrei als die Klasse.

Um diese Fehler zu beheben, verwenden Sie default anstelle von null für unbeschränkte Typparameter, fügen Sie bei Verwendung des as-Operators Klasseneinschränkungen hinzu, vermeiden Sie Schnittstellenvereinheitlichungskonflikte, erstellen Sie keine generischen Attributklassen und stellen Sie sicher, dass Typargumente der Sichtbarkeit ihrer umgebenden Mitglieder entsprechen.

  • Ersetzen Sie null Zuordnungen durch default(T) oder fügen Sie eine class Einschränkung (CS0403) hinzu. Wenn Sie einem nicht eingeschränkten Typparameter zuweisen null , kann der Compiler nicht garantieren, dass das Typargument ein Verweistyp ist, der Werte akzeptiert null , da es sich möglicherweise um einen Werttyp wie int oder struct, der nicht sein nullkann, handelt. Um diesen Fehler zu beheben, verwenden Sie default(T)entweder den entsprechenden Standardwert für jeden Typ (Null für Referenztypen, Null oder leer für Werttypen), oder fügen Sie dem Typparameter eine class Einschränkung hinzu, wenn Sie speziell Referenztypsemantik benötigen und Zuordnungen zulassen null möchten.
  • Fügen Sie bei Verwendung des class Operators (as) eine oder eine bestimmte Typeinschränkung hinzu. Der as Operator führt eine sichere Typumwandlung durch, die zurückgegeben null wird, wenn die Konvertierung fehlschlägt, dieses Verhalten ist jedoch nicht mit Werttypen kompatibel, da Werttypen nicht sein nullkönnen. Wenn Sie mit einem nicht eingeschränkten Typparameter verwenden as , kann der Compiler nicht garantieren, dass das Typargument kein Werttyp ist, sodass er den Code ablehnt. Um diesen Fehler zu beheben, fügen Sie eine class-Einschränkung oder eine bestimmte Verweistyp-Einschränkung (z. B. where T : SomeClass) hinzu, um sicherzustellen, dass der Typparameter immer ein Verweistyp ist, der das Ergebnis null einer fehlgeschlagenen Umwandlung ordnungsgemäß verarbeiten kann.
  • Vermeiden Sie die Implementierung derselben generischen Schnittstelle mehrmals mit Typparametern, die vereinheitlichen könnten (CS0695). Wenn eine Klasse eine generische Schnittstelle mehrmals mit unterschiedlichen Typparametern implementiert (wie class G<T1, T2> : I<T1>, I<T2>), besteht das Risiko, dass jemand sie mit demselben Typ für beide Parameter instanziieren könnte (G<int, int>), was einen Konflikt verursachen würde, da die Klasse implementiert und dadurch I<int> zweimal umgesetzt würde. Um diesen Fehler zu beheben, implementieren Sie entweder die Schnittstelle nur einmal, strukturieren Sie die Typparameter so, dass die Vereinigung verhindert wird, oder verwenden Sie separate nicht generische Klassen für unterschiedliche Spezialisierungen.
  • Entfernen von generischen Typparametern aus Attributklassen (CS0698).

    Hinweis

    Dieser Fehler wird in den aktuellen Versionen von C# nicht erstellt, da generische Attribute jetzt unterstützt werden.

  • Geben Sie explizit Typargumente an, wenn dynamische Werte an generische lokale Funktionen (CS8322) übergeben werden. Wenn Sie ein dynamic Argument an eine generische lokale Funktion übergeben, kann der Compiler keine Typargumente ableiten, da der tatsächliche Typ erst zur Laufzeit bekannt ist. Um diesen Fehler zu beheben, geben Sie explizit das Typargument an (z. B. LocalFunc<int>(d)), wandeln Sie den dynamischen Wert in den erwarteten Typ um oder verwenden Sie eine nicht-dynamische Variable.
  • Stellen Sie sicher, dass Typenargumente, die in öffentlichen oder geschützten Signaturen verwendet werden, mindestens so barrierefrei sind wie das Element, das sie verwendet (CS9338). Ein öffentliches oder geschütztes generisches Element muss Typargumente verwenden, die öffentlich zugänglich sind. Andernfalls konnte externer Code nicht ordnungsgemäß auf die Signatur des Mitglieds zugreifen oder sie nutzen. Wenn Sie beispielsweise public class Container<T> haben, wobei T ein interner Typ ist, können externe Assemblys zwar Container sehen, aber nicht ordnungsgemäß damit arbeiten, weil sie T nicht sehen können. Um diesen Fehler zu beheben, machen Sie entweder das Typargument öffentlich, oder senken Sie die Zugriffsebene des Elements, das es verwendet, um der Zugriffsebene des Typarguments zu entsprechen.

Weitere Informationen finden Sie unter Einschränkungen für Typparameter, Standardwertausdrücke und Attribute.

Gültige Einschränkungstypen

Die folgenden Fehler beziehen sich auf die Verwendung ungültiger Typen als Einschränkungen für generische Typparameter:

  • CS0405: Doppelte Einschränkung für typparameter.
  • CS0702: Einschränkung darf keine spezielle Klasse sein.
  • CS0703: Inkonsistente Zugänglichkeit: Einschränkungsart ist weniger zugänglich als die Deklaration.
  • CS0706: Ungültiger Einschränkungstyp. Ein typ, der als Einschränkung verwendet wird, muss eine Schnittstelle, eine nicht versiegelte Klasse oder ein Typparameter sein.
  • CS0717: static classStatische Klassen können nicht als Einschränkungen verwendet werden.

Eine Einschränkung muss eine Schnittstelle, eine nicht versiegelte Klasse oder ein Typparameter sein. Bestimmte Typen sind als Einschränkungen ungültig, entweder aufgrund ihrer besonderen Bedeutung im .NET-Typsystem oder weil sie nicht vererbt werden können.

So beheben Sie diese Fehler:

  • Entfernen doppelter Einschränkungen (CS0405). Jede Einschränkung kann nur einmal in einer Einschränkungsklausel angezeigt werden. Wenn Sie über das Duplikat verfügen where T : I, I, entfernen Sie das Duplikat.
  • Verwenden Sie keine speziellen Klassen als Einschränkungen (CS0702). Die Typen Object, Arrayund ValueType können nicht als Einschränkungen verwendet werden. Jeder Typ leitet sich bereits von Object ab, daher bringt eine Einschränkung darauf keinen Mehrwert. Array und ValueType sind abstrakte Basistypen, die nicht direkt geerbt werden können. Wenn Sie ein arrayähnliches Verhalten benötigen, verwenden Sie stattdessen IList<T> oder IEnumerable<T>.
  • Stellen Sie sicher, dass Einschränkungstypen mindestens so barrierefrei sind wie der generische Typ (CS0703). Ein öffentlicher generischer Typ kann keine Einschränkungen mit internen Typen aufweisen, da externer Code keine gültigen Typargumente bereitstellen kann. Entweder den Constraint-Typ öffentlich machen oder die Zugänglichkeit des generischen Typs verringern.
  • Verwenden Sie nur Schnittstellen, nicht versiegelte Klassen oder Typparameter als Einschränkungen (CS0706). Sie können keine Arrays, versiegelten Klassen, Strukturen, Enumerationen oder andere ungültige Typen als Einschränkungen verwenden. Wenn Sie ein bestimmtes Verhalten benötigen, sollten Sie eine Schnittstelle verwenden, die von den gewünschten Typen implementiert wird.
  • Verwenden Sie statische Klassen nicht als Einschränkungen (CS0717). Statische Klassen können nicht erweitert werden, da sie nur statische Member enthalten. Es kann kein Typ vorhanden sein, der von einer statischen Klasse abgeleitet ist und es als Einschränkung nutzlos macht. Verwenden Sie stattdessen eine nicht statische Klasse oder Schnittstelle.

Das folgende Beispiel zeigt gültige Einschränkungstypen:

public interface IMyInterface { }
public class MyBaseClass { }

// Valid: interface constraint
class A<T> where T : IMyInterface { }

// Valid: non-sealed class constraint
class B<T> where T : MyBaseClass { }

// Valid: type parameter constraint
class C<T, U> where T : U { }

Weitere Informationen finden Sie unter Einschränkungen für Typparameter (C#-Programmierhandbuch).

Einschränkungskonflikte und Zirkelabhängigkeiten

Die folgenden Fehler beziehen sich auf Konflikte zwischen Einschränkungen oder zirkulären Abhängigkeiten in Einschränkungsdeklarationen:

  • CS0454: Zirkeleinschränkungsabhängigkeit mit Typparameter 1 und Typparameter 2.
  • CS0455: Der Typparameter erbt widersprüchliche Einschränkungen.

Einschränkungen können keine Zirkelabhängigkeiten erstellen, und Typparameter können keine widersprüchlichen Einschränkungen erben, die nicht gleichzeitig erfüllt werden können.

So beheben Sie diese Fehler:

  • Zirkuläre Abhängigkeitsbeschränkungen entfernen (CS0454). Ein Typparameter kann nicht direkt oder indirekt durch seine Einschränkungen von sich selbst abhängig sein. Ein Beispiel wie where T : U where U : T führt zu einer Zirkelabhängigkeit, da T von U und U von T abhängt. Unterbrechen Sie den Zyklus, indem Sie eine der Einschränkungen entfernen.
  • Entfernen Sie konflikterende geerbte Einschränkungen (CS0455). Ein Typparameter kann nicht auf mehrere nicht verknüpfte Klassen beschränkt werden, da C# nicht die Vererbung mehrerer Klassen unterstützt. Ebenso kann sie nicht auf beide struct und einen Klassentyp beschränkt werden, da diese Einschränkungen sich gegenseitig ausschließen. Strukturieren Sie Die Typhierarchie neu, oder entfernen Sie eine der widersprüchlichen Einschränkungen.

Das folgende Beispiel zeigt die Probleme:

// CS0454: Circular dependency - T depends on U and U depends on T
class Circular<T, U> where T : U where U : T { }

// CS0455: Conflicting constraints - U can't derive from both B and B2
public class B { }
public class B2 { }
public class G<T> where T : B
{
    public class N<U> where U : B2, T { }
}

Weitere Informationen finden Sie unter Einschränkungen für Typparameter (C#-Programmierhandbuch).

Typparameterabweichung

Der folgende Fehler bezieht sich auf Varianzmodifizierer für generische Typparameter:

  • CS1961: Ungültige Varianz: Der Typparameter muss für den Typ gültig sein.

Varianzmodifizierer (in für Kontravarianz, out für Kovarianz) steuern, wie Sie Typparameter in Schnittstellen- und Delegatdeklarationen verwenden. Ein kovarianter (out) Typparameter kann nur in Ausgabepositionen (Rückgabetypen) angezeigt werden, während ein Kontravariant -inTypparameter () nur in Eingabepositionen (Parametertypen) angezeigt werden kann.

So beheben Sie diesen Fehler:

  • Verwenden Sie out (kovariant) für Typparameter, die nur in Rückgabetypen angezeigt werden. Die Kovarianz ermöglicht die Verwendung eines stärker abgeleiteten Typs, wo ein weniger abgeleiteter Typ erwartet wird.
  • Verwenden Sie in (Kontravariant) für Typparameter, die nur in Parametertypen angezeigt werden. Contravarianz ermöglicht es, einen weniger spezifizierten Typ in einem Kontext zu verwenden, in dem ein spezifizierterer Typ erwartet wird.
  • Entfernen Sie den Varianzmodifizierer, wenn der Typparameter sowohl in der Eingabe- als auch in der Ausgabeposition angezeigt werden muss.

Das folgende Beispiel zeigt die korrekte und falsche Varianzverwendung:

// Incorrect: out T can't appear in input position
interface IWrong<out T>
{
    void Method(T arg);  // CS1961
}

// Correct: out T only in output positions
interface ICovariant<out T>
{
    T GetValue();
}

// Correct: in T only in input positions
interface IContravariant<in T>
{
    void Process(T arg);
}

// No modifier needed for both input and output
interface IInvariant<T>
{
    T Transform(T arg);
}

Weitere Informationen finden Sie unter Kovarianz und Kontravarianz in Generics.