Beheben von Fehlern und Warnungen für Stellvertretungs- und Funktionszeiger

Dieser Artikel behandelt die folgenden Compiler-Fehler und -Warnungen:

  • CS0059: Inkonsistenter Zugriff: Parametertyp 'Typ' ist weniger zugreifbar als Delegat 'Delegat'.
  • CS0123: Keine Überladung für 'methode' stimmt mit dem Delegat 'delegat' überein.
  • CS0148: Der Delegat "Delegate" verfügt nicht über einen gültigen Konstruktor.
  • CS0410: Keine Überladung für „method“ hat die richtigen Parameter oder Rückgabetypen.
  • CS0644: "Klasse" kann nicht von der speziellen Klasse "Klasse" abgeleitet werden.
  • CS1599: Der Rückgabetyp einer Methode, eines Delegaten oder eines Funktionszeigers darf nicht 'typ' sein.
  • CS1958: Objekt- und Auflistungsinitialisierungsausdrücke werden möglicherweise nicht auf einen Stellvertretungserstellungsausdruck angewendet.
  • CS8755: "Modifizierer" kann nicht als Modifizierer für einen Funktionszeigerparameter verwendet werden.
  • CS8756: Der Funktionszeiger "type" nimmt keine "Count"-Argumente an.
  • CS8757: Keine Überladung für ‚method‘ entspricht Funktionszeiger ‚type‘.
  • CS8758: Referenzkonflikt zwischen 'Methodenparameter' und Funktionszeiger 'Typ'.
  • CS8759: Es kann kein Funktionszeiger für "Methode" erstellt werden, da es sich nicht um eine statische Methode handelt.
  • CS8786: Die Aufrufkonvention von 'Konvention' ist nicht mit 'Konvention' kompatibel.
  • CS8787: Methodengruppe kann nicht in Funktionszeiger konvertiert werden. (Fehlt ihnen ein '&'?)
  • CS8788: Eine Erweiterungsmethode mit einem Empfänger kann nicht als Ziel eines &-Operators verwendet werden.
  • CS8789: Der Typ eines in einer festen Anweisung deklarierten lokalen Typs kann kein Funktionszeigertyp sein.
  • CS8806: Die Aufrufkonvention der "Konvention" wird von der Sprache nicht unterstützt.
  • CS8807: "Bezeichner" ist kein gültiger Aufrufkonventionsbezeichner für einen Funktionszeiger.
  • CS8808: "Modifizierer" ist kein gültiger Funktionszeiger-Rückgabetypmodifizierer. Gültige Modifizierer sind "ref" und "ref readonly".
  • CS8809: Ein Rückgabetyp kann nur einen 'modifier' Modifizierer haben.
  • CS8811: Kann Methodengruppe 'method' nicht in Delegattyp 'type' konvertieren.
  • CS8909: Der Vergleich von Funktionszeigern kann zu einem unerwarteten Ergebnis führen, da Zeiger auf dieselbe Funktion unterschiedlich sein können.
  • CS8911: Die Verwendung eines Funktionszeigertyps in diesem Kontext wird nicht unterstützt.

Nichtübereinstimmungen bei Stellvertretungssignaturen

  • CS0059: Inkonsistente Zugänglichkeit: Parametertyp 'type' ist weniger zugänglich als Delegat 'delegate'.
  • CS0123: Keine Überladung für 'methode' stimmt mit dem Delegat 'delegat' überein.
  • CS0148: Der Delegat "delegate" verfügt nicht über einen gültigen Konstruktor.
  • CS0410: Keine Überladung für „method“ hat die richtigen Parameter oder Rückgabetypen.

Wenn Sie einen Delegaten erstellen oder zuweisen, überprüft der Compiler, ob die Signatur der Zielmethode mit der Deklaration des Delegatentyps übereinstimmt. Die Signatur enthält die Parametertypen, den Rückgabetyp und die Barrierefreiheit. Die vollständigen Regeln finden Sie unter Stellvertretungen und Barrierefreiheitseinschränkungen in der C#-Spezifikation.

  • Ändern Sie alle Parametertypen in der Delegatdeklaration zu Typen, die mindestens so zugänglich sind wie der Delegat selbst (CS0059). Ein public Delegat kann nicht auf einen weniger zugänglichen Typ in der Parameterliste verweisen, da Aufrufer außerhalb der Assembly das Argument nicht bereitstellen können. Weitere Informationen finden Sie unter Zugriffsmodifikatoren.
  • Passen Sie entweder die Methodensignatur oder die Stellvertretungssignatur an, damit die Parametertypen und der Rückgabetyp exakt übereinstimmen (CS0123). Der Compiler erfordert eine genaue Übereinstimmung der Signatur, wenn Sie einem Delegaten eine Methode zuweisen.
  • Überprüfen Sie, ob der Delegate von einem konformen Compiler (CS0148) kompiliert wurde. Dieser Fehler tritt auf, wenn Sie eine verwaltete Assembly importieren, die von einem Compiler erstellt wurde, der einen fehlerhaften Delegatkonstruktor erzeugt hat. Kompilieren Sie die Assembly mit einem standardskonformen Compiler, um den Fehler zu beheben.

Note

CS0410 wird nicht mehr vom aktuellen C#-Compiler erstellt. Die gleiche Bedingung erzeugt stattdessen CS0123. Ältere Assemblys, die mit früheren Compilern kompiliert wurden, verweisen möglicherweise weiterhin auf diesen Fehlercode.

CS0148 ist eine nur für den Build-Prozess bestimmte Diagnose.

Note

Diese Warnung wird nur während expliziter Build- oder Neuaufbau-Vorgängen gemeldet. Sie wird während der Eingabe in der IDE nicht als Teil der IntelliSense-Diagnose angezeigt. Dies bedeutet: Wenn Sie die Warnung mithilfe des Felds beheben oder entfernen, wird die Warnung möglicherweise in der Fehlerliste beibehalten, bis Sie das Projekt erstellen oder erneut erstellen.

Einschränkungen des Delegatentyps

  • CS0644: "Klasse" kann nicht von der speziellen Klasse "Klasse" abgeleitet werden.
  • CS1599: Der Rückgabetyp einer Methode, eines Delegaten oder eines Funktionszeigers darf nicht 'typ' sein.
  • CS1958: Objekt- und Sammlung-Initialisierungsausdrücke dürfen nicht auf einen Delegatenerstellungsausdruck angewendet werden.

Die C#-Sprache schränkt ein, wie Sie bestimmte spezielle Typen verwenden können, einschließlich System.Delegate. Die vollständigen Regeln für Stellvertretungsdeklarationen finden Sie unter Delegaten und Stellvertretungen in der C#-Spezifikation.

  • Entfernen Sie die explizite Basisklasse, und verwenden Sie stattdessen eine delegate Deklaration (CS0644). Klassen können nicht explizit von System.Delegate, System.Enum, System.ValueType oder System.Array erben. Der Compiler verwendet diese Typen als implizite Basisklassen. Beispielsweise wird jede delegate Deklaration implizit von System.Delegate abgeleitet.
  • Ändern Sie den Rückgabetyp in einen Typ, der als Rückgabewert zulässig ist (CS1599). Bestimmte Typen in der .NET Klassenbibliothek, z. B. TypedReference, RuntimeArgumentHandle und ArgIterator, können nicht als Rückgabetypen für Methoden, Stellvertretungen oder Funktionszeiger verwendet werden, da sie potenziell unsichere Stapelvorgänge aktivieren können.
  • Entfernen Sie die geschweiften Klammern nach dem Delegatenerstellungsausdruck (CS1958). Delegaten haben keine Mitglieder, die Sie über Objekt- oder Sammlungsinitialisierungssyntax festlegen können. Bei { } nach einem new DelegateType(method)-Ausdruck, entfernen Sie die geschweiften Klammern.

Unstimmigkeiten in Funktionszeigersignaturen

  • CS8755: "Modifizierer" kann nicht als Modifizierer für einen Funktionszeigerparameter verwendet werden.
  • CS8756: Der Funktionszeiger "type" nimmt keine "Count"-Argumente an.
  • CS8757: Keine Überladung für ‚method‘ entspricht Funktionszeiger ‚type‘.
  • CS8758: Verweiskonflikt zwischen 'Methode' und Funktionszeiger 'Typ'.
  • CS8759: Es kann kein Funktionszeiger für "Methode" erstellt werden, da es sich nicht um eine statische Methode handelt.
  • CS8787: Methodengruppe kann nicht in Funktionszeiger konvertiert werden. (Fehlt ihnen ein '&'?)
  • CS8788: Eine Erweiterungsmethode mit einem Empfänger kann nicht als Ziel eines &-Operators verwendet werden.
  • CS8811: Die Methodengruppe 'method' kann nicht in Delegatentyp 'type' konvertiert werden.

Wenn Sie einem Funktionszeiger mithilfe des Address-of&()-Operators eine Methode zuweisen, überprüft der Compiler, ob die Signatur der Methode dem Funktionszeigertyp entspricht. Die vollständigen Regeln für Funktionszeigerdeklarationen und -verwendung finden Sie unter Funktionszeiger und unsicherenCode.

  • Entfernen Sie den nicht unterstützten Modifizierer aus dem Funktionszeigerparameter (CS8755). Funktionszeigerparameter unterstützen nur ref, out, und in Modifizierer. Andere Parametermodifizierer, z. B. params, sind in Deklarationen von Funktionszeigertypen nicht gültig.
  • Ändern Sie die Anzahl der Argumente an der Aufrufwebsite so, dass sie der Parameteranzahl des Funktionszeigers (CS8756) entspricht. Der Funktionszeigertyp definiert eine feste Anzahl von Parametern, und Sie müssen genau so viele Argumente übergeben.
  • Passen Sie die Signatur der Methode so an, dass die Parametertypen, rückgabetyp und Parameteranzahl dem Funktionszeigertyp (CS8757) entsprechen. Im Gegensatz zu Delegaten unterstützen Funktionszeiger keine impliziten Konvertierungen zwischen kompatiblen Methodensignaturen. Die Übereinstimmung muss exakt sein.
  • Richten Sie die Modifizierer ref, out oder in zwischen den Parametern der Methode und den Parametern des Funktionszeigertyps aus (CS8758). Der Bezugstyp jedes Parameters muss exakt übereinstimmen. Ein ref-Parameter kann keine in- oder out-Position im Funktionszeigertyp erfüllen.
  • Ändern Sie die Zielmethode in static (CS8759). Funktionszeiger können nur auf statische Methoden verweisen, da sie unformatierte Funktionsadressen ohne zugeordnete Objektinstanz darstellen.
  • Fügen Sie bei der Zuweisung an einen Funktionszeiger den Operator & vor der Methodengruppe hinzu (CS8787). Im Gegensatz zu Delegaten benötigen Funktionszeiger die explizite Adresse des Operators: delegate*<void> ptr = &MyMethod;.
  • Verwenden Sie eine statische Methode anstelle einer Erweiterungsmethode mit einem Empfänger (CS8788). Der & Operator erfordert einen direkten Methodenverweis. Für eine Instanz aufgerufene Erweiterungsmethoden verfügen über einen impliziten Empfänger, der nicht in einem Funktionszeiger erfasst werden kann.
  • Entfernen Sie den & Operator, und verwenden Sie stattdessen die Stellvertretungssyntax, oder ändern Sie den Zieltyp von einem Delegaten in einen Funktionszeiger (CS8811). Der & Operator erzeugt einen Funktionszeiger und keine Stellvertretung. Um einer Delegatenklasse eine Methodengruppe zuzuweisen, lassen Sie das & weg und verwenden Sie die standardmäßige Delegat-Erstellungssyntax.

Konventionen und Rückgabetypen für Funktionszeigeraufrufe

  • CS8786: Die Aufrufkonvention von ‚convention‘ ist nicht kompatibel mit ‚convention‘.
  • CS8806: Die Aufrufkonvention von 'convention' wird in dieser Sprache nicht unterstützt.
  • CS8807: "Bezeichner" ist kein gültiger Aufrufkonventionsbezeichner für einen Funktionszeiger.
  • CS8808: "Modifizierer" ist kein gültiger Funktionszeiger-Rückgabetypmodifizierer. Gültige Modifizierer sind "ref" und "ref readonly".
  • CS8809: Ein Rückgabetyp kann nur einen ‚modifier‘ Modifikator haben.

Funktionszeigerdeklarationen umfassen eine Aufrufkonvention und optionale Rückgabetypmodifizierer. Der Compiler überprüft diese Optionen. Die vollständigen Regeln finden Sie unter Funktionszeiger.

  • Ändern Sie entweder die Aufrufkonvention der Methode oder die Aufrufkonvention des Funktionszeigertyps so, dass sie übereinstimmen (CS8786). Wenn Sie einem Funktionszeiger eine Methode zuweisen, müssen die aufrufenden Konventionen kompatibel sein. Eine Methode, die Cdecl verwendet, kann einem mit Stdcall deklarierten Funktionszeiger nicht zugewiesen werden.
  • Verwenden Sie eine unterstützte Aufrufkonvention in der Funktionszeigerdeklaration (CS8806). Die Sprache unterstützt managed und unmanaged. Verwenden Sie für eine bestimmte nicht verwaltete Konvention das unmanaged-Schlüsselwort mit der Konvention in eckigen Klammern, wie unmanaged[Cdecl], unmanaged[Stdcall], unmanaged[Thiscall] oder unmanaged[Fastcall].
  • Ersetzen Sie den ungültigen Bezeichner durch eine unterstützte Aufrufkonvention (CS8807). Verwenden Sie managed, unmanaged oder unmanaged mit einem Aufrufkonventionstyp in eckigen Klammern (z. B. unmanaged[Cdecl]).
  • Verwenden Sie nur ref oder ref readonly als Rückgabetypmodifizierer (CS8808). Andere Modifizierer, wie out oder in, sind für Rückgabetypen von Funktionszeigern nicht gültig.
  • Entfernen Sie den doppelten Rückgabetypmodifizierer, sodass nur ein ref Oder ref readonly angezeigt wird (CS8809). Der Compiler lässt höchstens einen Rückgabetypmodifizierer für eine Funktionszeigerdeklaration zu.

Einschränkungen für die Verwendung von Funktionszeigern

  • CS8789: Der Typ eines in einer festen Anweisung deklarierten lokalen Typs kann kein Funktionszeigertyp sein.
  • CS8909: Der Vergleich von Funktionszeigern kann zu einem unerwarteten Ergebnis führen, da Zeiger auf dieselbe Funktion unterschiedlich sein können.
  • CS8911: Die Verwendung eines Funktionszeigertyps in diesem Kontext wird nicht unterstützt.

Der Compiler schränkt ein, wie Funktionszeigertypen in bestimmten Kontexten verwendet werden können. Die vollständigen Regeln finden Sie unter Funktionszeiger.

  • Ändern Sie den lokalen Variablentyp in der fixed Anweisung in einen Datenzeigertyp anstelle eines Funktionszeigertyps (CS8789). Mit der fixed-Anweisung werden verwaltete Objekte im Arbeitsspeicher fixiert, um auf Daten zuzugreifen. Funktionszeiger stellen Codeadressen, keine Daten dar und können nicht angeheftet werden.
  • Vermeiden Sie den Vergleich von Funktionszeigern für die Gleichheit (CS8909). Diese Warnung gibt an, dass der Vergleich von Funktionszeigern mit == oder != zu unerwarteten Ergebnissen führen kann. Die Laufzeit gibt möglicherweise unterschiedliche Zeiger für dieselbe Funktion aufgrund von Implementierungsdetails wie Thunking oder JIT-Kompilierung zurück. Um die Warnung zu unterdrücken, wenn Sie bestätigen, dass der Vergleich beabsichtigt ist, verwenden Sie #pragma warning disable CS8909.
  • Verschieben sie die Verwendung des Funktionszeigers in einen unterstützten Kontext (CS8911). Funktionszeigertypen können nicht an bestimmten Positionen verwendet werden, z. B. Attributargumente oder typeof Ausdrücke. Strukturieren Sie den Code neu, um die Verwendung von Funktionszeigertypen in nicht unterstützten Kontexten zu vermeiden.