Dieser Artikel stellt hauptsächlich die relevanten Informationen zur C#-Inversion und -Kovarianz im Detail vor, die einen gewissen Referenzwert haben.
Dieser Artikel verwendet weitere Delegierte und Lambda-Ausdrücke Schauen Sie sich hierzu bitte meine Artikel „Delegierte und anonyme Delegierte“ und „Anonyme Delegierte und Lambda-Ausdrücke“ an, um Ihnen beim Aufbau eines vollständigen Wissenssystems zu helfen.
Im Prozess von C# von seiner Geburt bis zu seiner Entwicklung und seinem Wachstum werden ständig neue Wissenspunkte eingeführt. Kontravarianz und Kovarianz sind keine Originalität von C# und werden später eingeführt. Kontravarianz und Kovarianz gibt es auch in Java. Ich werde in Zukunft auch einen Artikel über Java-Kontravarianz und Kovarianz schreiben.
Kontravarianz und Kovarianz klingen abstrakt und tiefgreifend, sind aber eigentlich sehr einfach. Schauen Sie sich den folgenden Code an:
class Person { } class Student : Person { } class Teacher: Person { } class Program { static void Main(string[] args) { List<Person> plist = new List<Person>(); plist = new List<Student>(); plist = new List<Teacher>(); } }
Im obigen Code ist plist = new List
Zuweisungsvorgänge wie die oben genannten waren vor C# 4.0 nicht zulässig. Der Grund dafür, warum sie nicht zulässig sind, ist die Typensicherheit. Schauen Sie sich den folgenden Beispielcode an:
List<Person> plist = new List<Student>(); plist.Add(new Person()); plist.Add(new Student()); plist.Add(new Teacher());
Das folgende Beispiel geht davon aus, dass List
Aber die Situation hat sich nach C# 4.0 geändert. Es ist nicht so, dass „unmögliche Dinge passiert sind“, sondern dass die Flexibilität der Anwendung neue Anpassungen vorgenommen hat. Ebenso ist das obige Programm in C# 4.0 immer noch nicht zulässig, es tritt jedoch eine Ausnahme auf. Ab C# 4.0 dürfen in generischen Delegaten und generischen Schnittstellen Sondersituationen auftreten (im Wesentlichen sind keine besonderen Änderungen aufgetreten, die später erläutert werden). Das folgende Beispiel:
delegate void Work<T>(T item); class Person { public string Name { get; set; } } class Student : Person { public string Like { get; set; } } class Teacher : Person { public string Teach { get; set; } } class Program { static void Main(string[] args) { Work<Person> worker = (p) => { Console.WriteLine(p.Name); }; ; Work<Student> student_worker = (s) => { Console.WriteLine(s.Like); }; student_worker = worker; //此处编译错误 } }
Nach der bisherigen theoretischen Unterstützung ist der Fehler von student_worker = worker leicht zu verstehen. Der Zweck unseres Programms hier besteht jedoch darin, den Arbeiter als Work
1 Denn beim Aufruf von student_worker(s) werden tatsächlich Waker(s) ausgeführt, also der Typ der s-Variablen muss erfolgreich in den vom Worker benötigten Parametertyp konvertiert werden.
2. Sie müssen dem Compiler mitteilen, dass er Variablen vom Typ Work
Bedingung 1 Beim Aufruf von student_worker() fordert der Compiler an, dass der Parameter ein Objekt vom Typ „Student“ sein muss, das erfolgreich in ein Objekt vom Typ „Person“ konvertiert werden kann.
Bedingung 2 erfordert Anpassungen an der Woke-Delegiertendefinition. Die Anpassungen sind wie folgt:
delegate void WorkIn<in T>(T item);
Der Zweck der Änderung des Delegiertennamens in WorkIn ist Um Änderungen vor und nach der Delegation zu vermeiden, ist der entscheidende Punkt
delegate void WorkIn<in T>(T item); class Program { static void Main(string[] args) { WorkInwoker = (p) => { Console.WriteLine(p.Name); }; WorkIn student_worker = woker; student_worker(new Student() { Name="tom", Like="C#" }); } }
Die Situation, in der Typparameter Subtypen sein müssen und Zuweisungstypparameter übergeordnete Typwerte sein können, wird als Kontravarianz bezeichnet. Kontravarianz erfordert, dass die Typparameter von Generika in C# markiert werden. Obwohl Kontravarianz als Kontravarianz bezeichnet wird, sieht es nur formal so aus, als ob das übergeordnete Klassenobjekt der Unterklassenvariablen zugewiesen wird. Im Wesentlichen handelt es sich um die Typkonvertierung der Parameter beim Aufruf der Methode. Student s = new Person(), das ist unmöglich, das ist keine Kontravariante, es ist ein Fehler.
Wenn Sie den obigen Code in die folgende Form umwandeln können, können Sie die Inversion vergessen. Das Wesentliche ist wichtiger als das Phänomen.
Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung von Kontravarianz und Kovarianz in C#. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!