Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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
Tim 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
Tim 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
asOperator verwendet werden, da er weder über eine Klassentypeinschränkung noch über eine Einschränkung verfügtclass. - CS0417: Bezeichner: Beim Erstellen einer Instanz eines Variablentyps können keine Argumente bereitgestellt werden.
-
CS0449: Die Einschränkungen
class,struct,unmanaged,notnullunddefaultkö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- oderstruct-Einschränkung angeben. -
CS0451: Die
new()Einschränkung kann nicht mit derstructEinschrä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:
Tkann 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
delegatekann nicht als Einschränkung verwendet werden. Haben Sie gemeintSystem.Delegate? -
CS9012: Unerwartetes Schlüsselwort
record. Haben Sie gemeintrecord structoderrecord 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 gemeintrecord structoderrecord 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
whereKlausel 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.IDisposableinpublic 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,TKeyoderTValue) anstelle von konkreten Typen (wieintoderstring) 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>()inpublic 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 Variabledouble Tinnerhalb 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 classoderrecord struct(oder nurrecordfür einen Verweistyp) verwenden. DasrecordSchlü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 Sierecord class MyRecordoderrecord struct MyRecordund platzieren Sie nichtrecord, 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, ,unmanagednotnullunddefaultEinschrä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
classoderstructkann nicht angegeben werden. -
CS0451: Die
new()Einschränkung kann nicht mit derstructEinschränkung verwendet werden. -
CS9011: Schlüsselwort
delegatekann nicht als Einschränkung verwendet werden. Haben Sie gemeintSystem.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). Dienew()Einschränkung muss nach allen anderen Einschränkungen angezeigt werden. Ändern Sie z. B.where T : new(), IDisposableinwhere 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,notnulloderdefaultangeben, und dieses muss zuerst in der Einschränkungsliste stehen. DieclassundstructEinschränkungen schließen sich gegenseitig aus, ebenso wieclassundunmanaged. In einem nullablen Kontextclassimpliziertnotnullbereits, 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 derstructEinschränkung widerspricht. Entfernen Sie entweder die Klasseneinschränkung oder diestructEinschränkung. - Nicht kombinieren
new()mitstruct(CS0451). Alle Werttypen (Structs) haben implizit einen öffentlichen parameterlosen Konstruktor, sodass dienew()Einschränkung redundant ist, wenn sie mitstructkombiniert wird. Entfernen Sie die Einschränkungnew(), wenn Siestructverwenden. - Ersetzen durch
delegateSystem.Delegatein Einschränkungsklauseln (CS9011). DasdelegateSchlüsselwort wird zum Deklarieren von Delegattypen und nicht als Einschränkung verwendet. Verwenden SieSystem.Delegateden Einschränkungstyp, um einen Typparameter auf Stellvertretungstypen zu beschränken. Ändern Sie z. B.where T : delegateinwhere 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
__arglistverwenden (CS0224). Das__arglistSchlü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 dasparamsSchlü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 nichtMyList<int, string>. - Verwenden Sie nur gültige Typen als Typargumente (CS0306). Zeigertypen, wie z. B.
int*oderchar*, 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 SieIntPtrverwenden 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 erfordertIEnumerator<T>dieusing System.Collections.Generic;-Richtlinie, währendIEnumeratorinSystem.Collectionsist. - 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 dennewOperator 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. Dienew()Einschränkung bietet diese Garantie zur Kompilierungszeit, sodass der Compiler den entsprechenden Instanziierungscode generieren kann. Wenn Sie z. B. überclass C<T>mit einem MitgliedT t = new T();verfügen, müssen Sie die Deklaration inclass 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 einenew()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 dienew()-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 Argumentenew 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 ersetztTwerden. 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
Tim 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
Tim generischen Typ oder der generischen MethodeTypeorMethod<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 : BaseTypehat, mussBaseTypejedes Typargument durch eine implizite Verweiskonvertierung oder Identitätskonvertierung konvertierbar sein. Das Typargument mussBaseTypeselbst sein, sich vonBaseTypeableiten oderBaseTypeimplementieren, wenn es sich um eine Schnittstelle handelt. Implizite numerische Konvertierungen (z. B. vonshortzuint) 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 : SomeClasshaben, muss jede davon abgeleitete Klasse alspublic class B<T> : A<T> where T : SomeClassdeklariert 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 zwischenint?undint, 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, umobjectoder 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
asOperator verwendet werden, da er weder über eine Klassentypeinschränkung noch über eine Einschränkung verfügtclass. - 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
nullZuordnungen durchdefault(T)oder fügen Sie eineclassEinschränkung (CS0403) hinzu. Wenn Sie einem nicht eingeschränkten Typparameter zuweisennull, kann der Compiler nicht garantieren, dass das Typargument ein Verweistyp ist, der Werte akzeptiertnull, da es sich möglicherweise um einen Werttyp wieintoderstruct, der nicht seinnullkann, handelt. Um diesen Fehler zu beheben, verwenden Siedefault(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 eineclassEinschränkung hinzu, wenn Sie speziell Referenztypsemantik benötigen und Zuordnungen zulassennullmöchten. - Fügen Sie bei Verwendung des
classOperators (as) eine oder eine bestimmte Typeinschränkung hinzu. DerasOperator führt eine sichere Typumwandlung durch, die zurückgegebennullwird, wenn die Konvertierung fehlschlägt, dieses Verhalten ist jedoch nicht mit Werttypen kompatibel, da Werttypen nicht seinnullkönnen. Wenn Sie mit einem nicht eingeschränkten Typparameter verwendenas, kann der Compiler nicht garantieren, dass das Typargument kein Werttyp ist, sodass er den Code ablehnt. Um diesen Fehler zu beheben, fügen Sie eineclass-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 Ergebnisnulleiner 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 dadurchI<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
dynamicArgument 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, wobeiTein interner Typ ist, können externe Assemblys zwarContainersehen, aber nicht ordnungsgemäß damit arbeiten, weil sieTnicht 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
Objectab, daher bringt eine Einschränkung darauf keinen Mehrwert.ArrayundValueTypesind abstrakte Basistypen, die nicht direkt geerbt werden können. Wenn Sie ein arrayähnliches Verhalten benötigen, verwenden Sie stattdessenIList<T>oderIEnumerable<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 : Tführt zu einer Zirkelabhängigkeit, daTvonUundUvonTabhä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
structund 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.