Varianz (in/out) mit Interfaces und Delegates
Verstehen Sie die Varianz in C#: out für Produzenten (Kovarianz) und in für Konsumenten (Kontravarianz) bei Interfaces und Delegates.
Varianz (in/out) mit Interfaces und Delegates ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 3. 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 3 Lektionen.
Überblick über Varianz
Varianz ermöglicht es generischen Schnittstellen und Delegaten, mit Vererbung zu arbeiten.
- out = Kovarianz (Produzent)
- in = Kontravarianz (Konsument)
- Sicher, wenn die API nur T erzeugt oder nur konsumiert
Kovarianz-Demo
IEnumerable<out T> ist kovariant: Eine Sequenz von Katzen kann dort verwendet werden, wo eine Sequenz von Tieren erwartet wird.
using System;
using System.Collections.Generic;
public class Animal { public virtual string Name() { return "animal"; } }
public class Cat : Animal { public override string Name() { return "cat"; } }
public class Program
{
static void PrintAll(IEnumerable<Animal> animals)
{
foreach (Animal a in animals)
{
Console.WriteLine(a.Name());
}
}
public static void Main(string[] args)
{
List<Cat> cats = new List<Cat>();
cats.Add(new Cat());
// IEnumerable<Cat> -> IEnumerable<Animal> is allowed (out T)
PrintAll(cats);
}
}
Kontravarianz-Demo
IComparer<in T> ist kontravariant: Ein Vergleicher für Animal funktioniert auch für Cat, weil er T nur als Eingabe verwendet.
using System;
using System.Collections.Generic;
public class Animal { public string N; public Animal(string n){ N=n; } }
public class Cat : Animal { public Cat(string n) : base(n) {} }
// Comparer can compare any Animals
public class AnimalNameComparer : IComparer<Animal>
{
public int Compare(Animal x, Animal y)
{
return string.Compare(x == null ? "" : x.N, y == null ? "" : y.N, StringComparison.Ordinal);
}
}
public class Program
{
public static void Main(string[] args)
{
List<Cat> cats = new List<Cat>();
cats.Add(new Cat("Miso"));
cats.Add(new Cat("Ada"));
// IComparer<Animal> can be used as IComparer<Cat> (in T)
cats.Sort(new AnimalNameComparer());
foreach (Cat c in cats) Console.WriteLine(c.N);
}
}
Delegatvarianz
Delegates sind ebenfalls variant: Func<out TResult> (Produzent) und Action<in T> (Konsument).
using System;
public class Animal { public virtual string Speak(){ return "???"; } }
public class Cat : Animal { public override string Speak(){ return "meow"; } }
public class Program
{
static Animal MakeAnimal() { return new Animal(); }
static void HandleAnimal(Animal a) { Console.WriteLine(a.Speak()); }
public static void Main(string[] args)
{
// Func<Cat> can be used where Func<Animal> is expected? Yes, because TResult is out.
Func<Animal> maker = new Func<Cat>(delegate { return new Cat(); });
Console.WriteLine(maker().Speak());
// Action<Animal> can be used where Action<Cat> is expected? Yes, because T is in.
Action<Cat> catSink = new Action<Animal>(HandleAnimal);
catSink(new Cat());
}
}
Benutzerdefinierte variante Schnittstellen
Entwurfsregel: Kennzeichnen Sie Typparameter, die ausschließlich Werte liefern, mit out und solche, die ausschließlich Werte verarbeiten, mit in, um sichere Konvertierungen zu ermöglichen.
using System;
// Producer-only interface: out T
public interface ISource<out T>
{
T Get();
}
// Consumer-only interface: in T
public interface ISink<in T>
{
void Put(T item);
}
public class Animal { public string N; }
public class Cat : Animal { }
public class CatSource : ISource<Cat>
{
public Cat Get() { return new Cat(); }
}
public class AnimalSink : ISink<Animal>
{
public void Put(Animal a) { Console.WriteLine("Got animal"); }
}
public class Program
{
public static void Main(string[] args)
{
ISource<Animal> animals = new CatSource(); // out T allows upcast
ISink<Cat> cats = new AnimalSink(); // in T allows down-assign
animals.Get();
cats.Put(new Cat());
}
}
Tipps zur Varianz
Tipps:
- out-Parameter dürfen nur an Ausgabepositionen vorkommen (Rückgabetypen, kovariante Positionen).
- in-Parameter dürfen nur an Eingabepositionen vorkommen (Methodenparameter).
- Vermischen Sie beim Deklarieren der Varianz nicht das Erzeugen und Verarbeiten desselben T.
- Varianz gilt für Schnittstellen und Delegates, nicht für Klassen.
Schlüsselwort für Kovarianz
Zusammenfassung
Zusammenfassung: Verwenden Sie out für Produzenten (Kovarianz) und in für Konsumenten (Kontravarianz) bei Schnittstellen und Delegaten. Halten Sie APIs in eine Richtung ausgerichtet, um sichere Konvertierungen zu ermöglichen.
Häufig gestellte Fragen
Ist die Lektion „Varianz (in/out) mit Interfaces und Delegates“ kostenlos?
Ja — der vollständige Text von „Varianz (in/out) mit Interfaces und Delegates“ 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 3 Lektionen.
Was lerne ich in „Varianz (in/out) mit Interfaces und Delegates“?
Verstehen Sie die Varianz in C#: out für Produzenten (Kovarianz) und in für Konsumenten (Kontravarianz) bei Interfaces und Delegates. 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 2 von 3.
Wie lange dauert die Lektion „Varianz (in/out) mit Interfaces und Delegates“?
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
- Generische Methoden/Typen und Einschränkungen
- Varianz (in/out) mit Interfaces und Delegates
- Nullable-Referenztypen (Bewusstsein) und Annotations (C#-6-Muster)