Eine kurze Diskussion über die Verwendung von C#-Generika

黄舟
Freigeben: 2016-12-21 14:48:58
Original
1221 Leute haben es durchsucht

Warum C#-Generika verwenden?

Um dieses Problem zu verstehen, schauen wir uns zunächst den folgenden Code an. Der Code lässt einige Inhalte weg, aber die Funktion besteht darin, einen Stapel zu implementieren, der nur int verarbeiten kann Datentyp:

public class Stack { This.m_item = new int[i] } } Der obige Code läuft sehr gut, aber was sollen wir tun, wenn wir einen Stack zum Speichern des String-Typs benötigen? Viele Leute werden darüber nachdenken, den obigen Code zu kopieren und int in einen String zu ändern. Natürlich ist daran nichts auszusetzen, aber ein gutes Programm wird dies nicht tun, weil er darüber nachdenkt, was zu tun ist, wenn er in Zukunft erneut einen Long- oder Node-Typ-Stack benötigt? Möchten Sie erneut kopieren? Ausgezeichnete Programmierer werden darüber nachdenken, ein gemeinsames Datentypobjekt zu verwenden, um diesen Stapel zu implementieren: ){...} public Stack(int i) { this.m_item = new[i]; Dieser Stapel ist sehr flexibel und kann Man kann sagen, dass dies ein für alle Mal erledigt ist. Aber im Großen und Ganzen ist es nicht ohne Mängel. Die wichtigsten Erscheinungsformen sind:

Wenn Stack Werttypen verarbeitet, werden Boxing- und Faltvorgänge ausgeführt, die eine große Anzahl von Variablen auf dem verwalteten Heap zuweisen und wiederverwenden Wenn die Datenmenge groß ist, ist der Leistungsverlust sehr schwerwiegend.

Obwohl es bei der Verarbeitung von Referenztypen keine Box- oder Faltoperation gibt, wird die Datentyp-Zwangsoperation verwendet, was die Belastung des Prozessors erhöht.

Es gibt schwerwiegendere Probleme mit der Datentyperzwingung (vorausgesetzt, Stack ist eine Instanz von Stack):

Node1 x = new Node1(); ; Der obige Code ist beim Kompilieren völlig in Ordnung, aber da Daten vom Typ Node1 übertragen werden, müssen sie beim Pop in den Typ Node2 konvertiert werden, was dazu führt, dass das Programm zu diesem Zeitpunkt ausgeführt wird entging der Compilerprüfung.

Um das Problem des Objekttypstapels zu lösen, führen wir Generika ein, die diese Probleme elegant lösen können. Generics verwenden einen übergebenen Datentyp T anstelle von Objekt. Der Typ von T wird beim Instanziieren der Klasse automatisch in lokalen Code kompiliert. Die Betriebseffizienz und die Codequalität werden erheblich verbessert . Sicherheit.

Verwendung von C#-Generika

Im Folgenden wird der obige Stapel mithilfe von Generika neu geschrieben, wobei ein gemeinsamer Datentyp T als Platzhalter verwendet wird und stattdessen darauf gewartet wird, dass ein tatsächlicher Wert während des Instanziierungstyps verwendet wird. Werfen wir einen Blick auf die Leistungsfähigkeit von Generika:

public class Stack { (int i) { this.m_item = new T[i]; Die Schreibmethode der Klasse bleibt dieselbe. Sie führt lediglich das Allgemeine ein Datentyp T, kann auf jeden Datentyp angewendet werden und ist typsicher. Aufrufende Methode dieser Klasse:

//Instantiierung kann nur Klassen vom Typ int speichern a = new Stack(100); Datentyp int x = a.Pop(); // Instanziierung kann nur Klassen vom Typ string speichern b = new Stack(100); b.Push(10); // Diese Zeile wird nicht kompiliert, da Klasse b nur Daten vom Typ String empfängt b.Push("8888"); Diese Klasse unterscheidet sich vollständig von der von implementierten Klasse Objekt:

1. Es ist typsicher. Wenn ein Stapel vom Typ int instanziiert wird, können Daten vom Typ string nicht verarbeitet werden, und das Gleiche gilt auch für andere Datentypen.

2. Kartons müssen nicht verpackt und gefaltet werden. Wenn diese Klasse instanziiert wird, wird lokaler Code entsprechend dem übergebenen Datentyp generiert. Der Datentyp des lokalen Codes wurde bestimmt, sodass kein Boxen und Falten erforderlich ist.

3. Keine Typkonvertierung erforderlich.

Theoretische Kenntnisse:

Die sogenannten Generika: Verwendung parametrisierter Typen, um mehrere Datentypen im selben Code zu betreiben. Generische Programmierung ist ein Programmierparadigma, das „parametrisierte Typen“ verwendet, um Typen zu abstrahieren und eine flexiblere Wiederverwendung zu erreichen.

C#-Generika verleihen dem Code eine stärkere Typsicherheit, bessere Wiederverwendung, höhere Effizienz und klarere Einschränkungen.

Generische C#-Funktionen werden von der CLR zur Laufzeit unterstützt, was sich vom Vorlagenmechanismus von C++ zur Kompilierungszeit und der „Wischmethode“ von Java zur Kompilierungszeit unterscheidet. Dadurch können generische Funktionen nahtlos zwischen CLR-fähigen Sprachen zusammenarbeiten.

Wenn generischer C#-Code in IL und Metadaten kompiliert wird, werden spezielle Platzhalter verwendet, um generische Typen darzustellen, und proprietäre IL-Anweisungen werden verwendet, um generische Operationen zu unterstützen. Die eigentliche generische Instanziierungsarbeit erfolgt „auf Abruf“ während der JIT-Kompilierung.

Der generische C#-Kompilierungsmechanismus ist wie folgt:

Während der ersten Kompilierungsrunde generiert der Compiler nur IL-Code und Metadaten der „generischen Version“ für den Stack-Typ und führt keine generische Ausführung aus Bei den Instanziierungsarten fungiert T lediglich als Platzhalter in der Mitte.

Wenn der JIT-Compiler während der JIT-Kompilierung zum ersten Mal auf Stack trifft, ersetzt er T – in der „generischen Version“ IL-Code und Metadaten durch den int-Typ, um den generischen Typ zu instanziieren.

CLR generiert den gleichen Code für alle generischen Typen, deren Typparameter „Referenztypen“ sind. Wenn der Typparameter jedoch ein „Werttyp“ ist, generiert die CLR ihn für jeden unterschiedlichen „Werttyp“ A separat Code.

Mehrere Funktionen von C#-Generika

Wenn die Parameter des instanziierten generischen Typs gleich sind, verwendet der JIT-Compiler den Typ wieder, sodass die dynamische Generika-Funktion von C# vermeidet, dass statische C++-Vorlagen zu einer Aufblähung des Codes führen können .

Generische C#-Typen enthalten umfangreiche Metadaten, sodass die generischen C#-Typen auf leistungsstarke Reflexionstechnologie angewendet werden können.

C#s Generika verwenden die Einschränkungsmethode „Basisklasse, Schnittstelle, Konstruktor, Werttyp/Referenztyp“, um „explizite Einschränkungen“ für Typparameter zu implementieren, was die Typsicherheit verbessert, aber auch die hohe Flexibilität von C++-Vorlagen einbüßt zu impliziten Einschränkungen von „Signaturen“.

Wenn eine generische C#-Klasse kompiliert wird, wird zuerst der Zwischencode IL generiert und der allgemeine Typ T ist nur ein Platzhalter. Beim Instanziieren einer Klasse wird T durch den vom Benutzer angegebenen Datentyp ersetzt und der lokale Code wird vom Just-in-Time-Compiler (JIT) generiert. Der tatsächliche Datentyp wurde in diesem lokalen Code verwendet, was äquivalent ist Die Klasse wurde mit dem tatsächlichen Typ geschrieben und ist daher unterschiedlich. Der native Code einer geschlossenen Klasse ist unterschiedlich. Nach diesem Prinzip können wir es uns so vorstellen: Verschiedene geschlossene Klassen generischer Klassen sind unterschiedliche Datentypen.

Auf diese Weise sind Generika nicht nur flexibler, sondern bringen auch Einfachheit und Einfachheit des Codes auf ein neues Niveau! Kein spezifischer Code mehr für verschiedene überladene Methoden schreiben!

C#-Generika sind eine unschätzbare Bereicherung im Arsenal der Entwicklungstools. Sie verbessern Leistung, Typsicherheit und Qualität, reduzieren sich wiederholende Programmieraufgaben und vereinfachen das gesamte Programmiermodell – und das alles durch eine elegante, lesbare Syntax. Obwohl die Wurzeln der C#-Generika C++-Vorlagen sind, bringt C# die Generika auf die nächste Ebene, indem es Sicherheit und Unterstützung zur Kompilierungszeit bietet. C# nutzt die Zwei-Phasen-Kompilierung, Metadaten und innovative Konzepte wie Einschränkungen und allgemeine Methoden. Es besteht kein Zweifel, dass zukünftige Versionen von C# die Generika weiterentwickeln werden, um neue Funktionen hinzuzufügen und die Generika auf andere .NET Framework-Bereiche wie Datenzugriff oder Lokalisierung auszudehnen.

Das ist alles, was die Verwendung von C# betrifft. Generika, bitte beachten Sie die chinesische PHP-Website (www.php.cn) für weitere verwandte Inhalte!


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage