Auflösung von Extension Methods
Verstehen Sie, wie der Compiler Extensions findet.
Auflösung von Extension Methods ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Wie der Compiler Erweiterungen findet
Wenn Sie value.Method() schreiben und keine passende Instanzmethode vorhanden ist, sucht der Compiler nach einer Erweiterungsmethode. Dabei berücksichtigt er jedoch nur Erweiterungen, deren enthaltender Namespace über eine using-Direktive im Gültigkeitsbereich liegt.
using-Direktiven bringen Erweiterungen in den Gültigkeitsbereich
Eine Erweiterungsmethode ist nur sichtbar, wenn Sie ihren Namespace importieren. Ohne das richtige using scheint die Methode nicht zu existieren, obwohl sie in die Assembly kompiliert wurde.
using System;
using MyHelpers; // brings StringExtensions into scope
namespace MyHelpers
{
public static class StringExtensions
{
public static string Reverse(this string s)
{
var arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("hello".Reverse());
}
}Instanzmethoden werden zuerst geprüft
Der Compiler löst den Aufruf schrittweise auf: Zuerst sucht er nach einer passenden Instanzmethode, einschließlich geerbter Methoden. Erst wenn keine davon passt, sucht er nach Erweiterungsmethoden.
using System;
using System.Collections.Generic;
public static class ListExt
{
// Ignored: List<int> already has Add(int)
public static void Add(this List<int> list, int a, int b)
=> list.Add(a + b);
}
public class Program
{
public static void Main()
{
var list = new List<int>();
list.Add(5); // the built-in instance Add wins for this signature
Console.WriteLine(list[0]);
}
}Näher gelegene Namespaces werden bevorzugt
Wenn zwei Erweiterungsmethoden passen, gewinnt die Methode, deren Namespace in der Verschachtelungshierarchie näher liegt. Eine Mehrdeutigkeit, die der Compiler nicht auflösen kann, führt zu einem Kompilierungsfehler und zwingt Sie zur eindeutigen Auswahl.
using System;
namespace Outer
{
public static class A { public static string Tag(this int n) => "A" + n; }
namespace Inner
{
public static class B { public static string Tag(this int n) => "B" + n; }
public class Program
{
public static void Main()
{
// B is in the nearer (Inner) namespace, so it is preferred
Console.WriteLine(7.Tag());
}
}
}
}Mehrdeutigkeiten durch einen statischen Aufruf auflösen
Wenn Erweiterungsmethoden miteinander kollidieren oder Sie den Aufruf ausdrücklich machen möchten, rufen Sie die statische Methode direkt über ihren vollständigen Klassennamen auf. Dadurch umgehen Sie die Auflösung von Erweiterungsmethoden vollständig.
using System;
public static class FormatExt
{
public static string Bracket(this string s) => "[" + s + "]";
}
public class Program
{
public static void Main()
{
// Explicit static call, no ambiguity possible
Console.WriteLine(FormatExt.Bracket("x"));
}
}Überladungsauflösung unter Erweiterungsmethoden
Wenn mehrere Erweiterungsmethoden denselben Namen haben, wählt die normale Überladungsauflösung anhand der Parametertypen die beste Übereinstimmung – genau wie bei gewöhnlichen überladenen Methoden.
using System;
public static class PrintExt
{
public static string Describe(this int n) => "int:" + n;
public static string Describe(this string s) => "str:" + s;
}
public class Program
{
public static void Main()
{
Console.WriteLine(42.Describe());
Console.WriteLine("hi".Describe());
}
}Generische Typinferenz bei der Auflösung
Bei generischen Erweiterungsmethoden leitet der Compiler die Typargumente aus dem Empfänger und den Argumenten ab. Wenn die Inferenz fehlschlägt, wird die Erweiterungsmethode nicht berücksichtigt.
using System;
using System.Collections.Generic;
public static class SeqExt
{
public static T FirstItem<T>(this IEnumerable<T> source)
{
foreach (var item in source) return item;
throw new InvalidOperationException("empty");
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 5, 6, 7 };
// T inferred as int from the List<int> receiver
Console.WriteLine(nums.FirstItem());
}
}Globale using-Direktiven und implizite Importe
Modernes C# kann global using-Direktiven deklarieren, sodass ein Namespace im gesamten Projekt im Gültigkeitsbereich liegt. Dadurch stehen gemeinsam genutzte Erweiterungsbibliotheken überall zur Verfügung, ohne dass Importe wiederholt werden müssen.
using System;
// In a real project a separate file might say: global using MyHelpers;
namespace MyHelpers
{
public static class IntExt { public static int Twice(this int n) => n * 2; }
}
public class Program
{
public static void Main()
{
// Works here because MyHelpers is referenced explicitly
Console.WriteLine(MyHelpers.IntExt.Twice(8));
}
}Wann der Empfängertyp eine Rolle spielt
Die Auflösung hängt vom statischen Typ des Empfängers ab, nicht von seinem Laufzeittyp. Eine für einen Basistyp deklarierte Erweiterungsmethode gilt auch dann, wenn die Variable eine abgeleitete Instanz enthält – es sei denn, eine spezifischere Erweiterungsmethode liegt im Gültigkeitsbereich.
using System;
public class Animal { }
public class Cat : Animal { }
public static class AnimalExt
{
public static string Kind(this Animal a) => "animal";
}
public class Program
{
public static void Main()
{
Animal a = new Cat();
// Chosen by static type Animal
Console.WriteLine(a.Kind());
}
}Ein Denkmodell für die Auflösung
Stellen Sie sich die Reihenfolge so vor: (1) Instanzmethoden, dann (2) Erweiterungsmethoden aus importierten Namespaces, beginnend mit dem nächstgelegenen, und anschließend (3) die Überladungsauflösung unter den Kandidaten. Wenn Sie diese Reihenfolge kennen, lassen sich fast alle überraschenden Ergebnisse erklären.
using System;
public static class Ext
{
public static string Wrap(this string s) => "<" + s + ">";
}
public class Program
{
public static void Main()
{
// No instance Wrap exists, so the extension is used
Console.WriteLine("node".Wrap());
}
}Probieren Sie es selbst aus
Definieren Sie eine Erweiterungsmethode in einem Namespace, importieren Sie ihn und rufen Sie die Methode auf. Rufen Sie dieselbe Methode anschließend ausdrücklich als statische Methode auf, um zu sehen, dass beide Wege funktionieren.
using System;
using Text.Helpers;
namespace Text.Helpers
{
public static class StringExtensions
{
public static int Vowels(this string s)
{
int count = 0;
foreach (var c in s.ToLower())
if ("aeiou".IndexOf(c) >= 0) count++;
return count;
}
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("education".Vowels());
Console.WriteLine(Text.Helpers.StringExtensions.Vowels("education"));
}
}Kurze Überprüfung
Überlegen Sie, wodurch eine Erweiterungsmethode sichtbar wird.
Zusammenfassung
Die Auflösung von Erweiterungsmethoden folgt einer klaren Reihenfolge.
- Instanzmethoden werden zuerst versucht; Erweiterungsmethoden schließen nur vorhandene Lücken.
- Eine Erweiterungsmethode ist nur sichtbar, wenn ihr Namespace über
usingoderglobal usingim Gültigkeitsbereich liegt. - Näher gelegene Namespaces werden bevorzugt; nicht auflösbare Gleichstände führen zu Kompilierungsfehlern.
- Sie können die statische Methode jederzeit ausdrücklich aufrufen, um eine Mehrdeutigkeit aufzulösen.
- Die Auflösung verwendet den statischen Typ des Empfängers.
Häufig gestellte Fragen
Ist die Lektion „Auflösung von Extension Methods“ kostenlos?
Ja — der vollständige Text von „Auflösung von Extension Methods“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Auflösung von Extension Methods“?
Verstehen Sie, wie der Compiler Extensions findet. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C# Academy zu starten?
Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Auflösung von Extension Methods“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?
Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Extension Methods definieren
- Interfaces und Generics erweitern
- Auflösung von Extension Methods
- Gute Extensions entwerfen