Heim Backend-Entwicklung C#.Net-Tutorial Generische C#-Programmierung

Generische C#-Programmierung

Dec 21, 2016 pm 02:47 PM

Generika: Verwenden Sie parametrisierte Typen, um mehrere Datentypen mit demselben Code zu betreiben. Verwenden Sie „parametrisierte Typen“, um Typen zu abstrahieren und eine flexible Wiederverwendung zu erreichen.

Beispielcode:

class PROgram

{

static void Main(string[] args)

{

int obj = 2;

Test test = new Test(obj);

Console.WriteLine("int:" + test.obj);

string obj2 = "hello world";

Test test1 = new Test(obj2);

Console.WriteLine("String:" + test 1 . obj);

Console.Read();

}

}



class Test

{

public T obj;

public Test(T obj)

{

this.obj = obj;

}

}

Das Ausgabeergebnis ist:

int:2

String:hello world



Programmanalyse:

1. Test ist eine generische Klasse. T ist der generische Typ, der instanziiert werden soll. Wenn T als Typ int instanziiert wird, dann ist die Mitgliedsvariable obj vom Typ int. Wenn T als Typ string instanziiert wird, dann ist obj vom Typ string.

2. Je nach Typ zeigt das obige Programm unterschiedliche Werte an.



Generischer C#-Mechanismus:

Generische C#-Funktionen werden von CLR zur Laufzeit unterstützt: Generischer C#-Code verwendet spezielle Methoden beim Kompilieren in IL-Code und Metadaten. Zur Darstellung werden Platzhalter verwendet generische Typen und generische Operationen werden mithilfe proprietärer IL-Anweisungen unterstützt. Die eigentliche generische Instanziierungsarbeit erfolgt „auf Abruf“ während der JIT-Kompilierung.



Sehen Sie sich gerade die Metadaten der Main-Funktion im Code an

.method private hidebysig static void Main(string[] args) cil verwaltet

{

.entrypoint

// Codegröße 79 (0x4f)

.maxstack 2

.locals init ([0] int32 obj,

1)

il_0000: nop

il_0001: ldc.i4.2

il_0002: stloc.0

il_0003: ldloc: ldloc. .0

IL_0004: newobj-Instanz void class CSharpStudy1.Test`1::.ctor(!0)

IL_0009: stloc.1

IL_000a: " ldstr "int:"

IL_000f: ldloc.1

IL_0010: ldfld !0 class CSharpStudy1.Test`1::obj

IL_0015: box [mscorlib ]System.Int3 2

IL_001a: Call String [mscorlib]System.String::Concat(object,

🎜> IL_001f: Call void [mscorlib]System.Console::WriteLine(string )

IL_0024: nop

IL_0025: ldstr „Hallo Welt“

IL_002a: stloc.2

IL_002b: ldloc.2

IL_002c: newobj-Instanz, leere Klasse CSharpStudy1.Test`1::.ctor(!0)

IL_0031: stloc.3

IL_0032: ldstr "String:"

IL_0037: ldloc.3

IL_0038: ldfld !0 class CSharpStudy1.Test`1& lt;string> : :obj

IL_003d: Call String [mscorlib]System.String::Concat(string,

String)

IL_0042: Call void [mscorlib]System.Console: : WriteLine(string)

IL_0047: nop

IL_0048: call int32 [mscorlib]System.Console::Read()

IL_004d: pop

IL_004 e : ret

} // end of method Program::Main



Werfen wir einen Blick auf die Metadaten des Konstruktors in der Testklasse

.method public hidebysig specialname rtspecialname

Instanz void .ctor(!T obj) cil verwaltet

{

// Codegröße 17 (0x11)

.maxstack 8

IL_0000: ldarg.0

IL_0001: Aufrufinstanz void [mscorlib]System.Object::.ctor()

IL_0006: nop

IL_0007 : nop

IL_0008: ldarg.0

IL_0009: ldarg.1

IL_000a: stfld !0 class ConsoleCSharpTest1.Test`1 ::obj

IL_000f: nop

IL_0010: ret

} // Ende der Methode Test`1::.ctor



1. Während einer Kompilierungsrunde generiert der Compiler nur die „generische Version“ des IL-Codes und der Metadaten für den Test-Typ – er instanziiert den generischen Typ nicht und T fungiert nur als Platzhalter in der Mitte. Beispiel:

wird in den Testtyp-Metadaten 2 angezeigt. Wenn der JIT-Compiler während der JIT-Kompilierung zum ersten Mal auf Test trifft, ersetzt er die „generische Version“ durch int T in IL-Code und Metadaten – Instanziierung generischer Typen. Beispiel:

wird in der Hauptfunktion 3 angezeigt. CLR generiert den gleichen Code für alle generischen Typen, deren Typparameter „Referenztypen“ sind. für jeden Ein anderer „Werttyp“, für den die CLR einen separaten Code generiert. Denn beim Instanziieren eines generischen Referenztyps ist die im Speicher zugewiesene Größe gleich, beim Instanziieren eines Werttyps ist die im Speicher zugewiesene Größe jedoch unterschiedlich.



Generische C#-Funktionen:

1 Wenn die Parameter des instanziierten generischen Typs identisch sind, verwendet der JIT-Editor den Typ wieder, sodass die dynamischen Generika von C# verwendet werden. Typfunktionen vermeiden das Problem der Codeaufblähung, das durch statische C++-Vorlagen verursacht werden kann.

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

3. Die Generika von C# verwenden die Einschränkungsmethode „Basisklasse, Schnittstelle, Konstruktor, Werttyp/Referenztyp“, um „explizite Einschränkungen“ für Typparameter zu implementieren, was nicht nur die Typsicherheit verbessert, sondern auch den Verlust von die hohe Flexibilität von C++-Vorlagen, die auf impliziten „Signatur“-Einschränkungen basieren



Generische C#-Vererbung:

C# Zusätzlich zur Möglichkeit, generische Typen separat zu deklarieren ( Zusätzlich zu Klassen und Strukturen) können Sie auch Deklarationen generischer Typen in Basisklassen einbinden. Wenn es sich bei der Basisklasse jedoch um eine generische Klasse handelt, wird ihr Typ entweder instanziiert oder von den von der Unterklasse deklarierten Typparametern abgeleitet (auch ein generischer Typ). 🎜>
Klasse D:C

Klasse E:C

Klasse F:C< ; string,int>

class G:C //Illegal

Der E-Typ stellt U und V für den C-Typ bereit, der von der oben genannten Unterklasse abgeleitet ist

Der F-Typ erbt von C. Ich persönlich denke, dass er als F-Erbung einer nicht generischen Klasse angesehen werden kann.

Der G-Typ ist nicht generisch und C Ist Generics, kann G keine generische Instanziierung für C bereitstellen



Mitglieder eines generischen Typs:

Mitglieder eines generischen Typs können Typparameter in der generischen Typdeklaration verwenden. Wenn der Typparameter jedoch keine Einschränkungen aufweist, können Sie für den Typ nur öffentliche Mitglieder verwenden, die von System.Object geerbt wurden. Wie unten gezeigt:




Generische Schnittstelle:

Die Typparameter der generischen Schnittstelle werden entweder instanziiert oder von den von der Implementierungsklasse deklarierten Typparametern abgeleitet



Generischer Delegat:

Generischer Delegat unterstützt die Anwendung von Parametertypen auf Delegaten-Rückgabewerte und -Parameter. Diese Parametertypen können auch mit rechtlichen Einschränkungen verbunden sein

Delegat bool MyDelegate(T-Wert);

class MyClass

{

static bool F(int i){...}

static bool G(string s){...}

static void Main()

{

MyDelegate

MyDelegate p1 = new MyDelegate(F);

}

}



Generische Methode:

1. Der generische C#-Mechanismus unterstützt nur „Typparameter in der Methodendeklaration“ – also generische Methoden.

2. Der generische C#-Mechanismus unterstützt nicht die Einbeziehung von Typparametern in die Deklaration anderer Mitglieder (einschließlich Eigenschaften, Ereignisse, Indexer, Konstruktoren, Destruktoren), außer Methoden, aber diese Mitglieder selbst können in einem generischen Element enthalten sein Typ und verwenden Sie die Typparameter des generischen Typs.

3. Generische Methoden können sowohl in generischen als auch in nicht generischen Typen enthalten sein.



Generische Methodendeklaration: wie folgt

public static int FunctionName(T value){...}



Überladung generischer Methoden:

public void Function1(T a);

public void Function1(U a);

So geht es kann keine Überladung einer generischen Methode darstellen. Da der Compiler nicht feststellen kann, ob die generischen Typen T und U unterschiedlich sind, kann er nicht feststellen, ob die beiden Methoden unterschiedlich sind



public void Function1(int x);

public void Function1(int x);

Dies kann eine Überlastung darstellen



public void Function1(T t) where T:A;

public void Function1(T t) where T:B;

Dies kann keine Überladung einer generischen Methode darstellen. Da der Compiler nicht feststellen kann, ob A und B in den Einschränkungen unterschiedlich sind, kann er nicht feststellen, ob die beiden Methoden unterschiedlich sind.



Generisches Methodenumschreiben:

in Während des Umschreibens Im Prozess werden die Einschränkungen abstrakter Methoden in abstrakten Klassen standardmäßig geerbt. Wie folgt:

abstract class Base

{

public abstract T F(T t,U u) wobei U:T;

öffentliche Zusammenfassung T G(T t) wobei T:IComparable;

}



class MyClass:Base

{

öffentliche Überschreibung
}

Für die beiden überschriebenen Methoden in MyClass ist die

F-Methode zulässig und die Einschränkungen werden standardmäßig vererbt

G-Methode ist unzulässig, angegeben Alle Einschränkungen sind überflüssig



Generische Einschränkungen:

1 C#-Generika erfordern alle Einschränkungen für „Typparameter aller generischen Typen oder generischen Methoden“. Annahmen basieren auf „expliziten Einschränkungen“, um die von C# geforderte Typsicherheit aufrechtzuerhalten.

2. „Explizite Einschränkungen“ werden durch where-Klauseln ausgedrückt, und Sie können vier Arten von Einschränkungen angeben: „Basisklasseneinschränkungen“, „Schnittstelleneinschränkungen“, „Konstruktoreinschränkungen“ und „Werttyp/Referenztyp“. Einschränkungen“.

3. „Explizite Einschränkungen“ sind nicht erforderlich. Wenn „explizite Einschränkungen“ nicht angegeben sind, können generische Typparameter nur auf öffentliche Methoden im System.Object-Typ zugreifen. Beispiel: Im ersten Beispiel ist die obj-Mitgliedsvariable definiert. Beispielsweise fügen wir dem ersten Beispiel eine Test1-Klasse hinzu und definieren darin zwei öffentliche Methoden Func1 und Func2, wie unten gezeigt:






Unten Beginnen Sie mit der Analyse dieser Einschränkungen:

Basisklasseneinschränkungen:

Klasse A

{

public void Func1()

{ }

}



Klasse B

{

public void Func2()

{ }

}



Klasse C

wobei S : A

wobei T : B

{

öffentliches C(S s,T t)

{

//S's Variable kann die Func1-Methode aufrufen

                 s.Func1(); >
}

}

Schnittstellenbeschränkung:

Schnittstelle IA< ;T>

{

T Func1();

}



Schnittstelle IB

{

void Func2();

}



interface IC

{

class MyClass< T, V>

wobei T: IA

wobei V: IB, IC

{

public MyClass (T, v)
{

// T kann Func1 aufrufen

T.Func1 ();

// v Objekte können Func2 und Func3 aufrufen

            v.Func2(); 🎜> Konstruktoreinschränkung:

Klasse A

                                                                                         🎜>

Klasse B

🎜>


Klasse C wobei T : new()

{

T t;

public C()

            {

t = new T();

}

}



Klasse D

          {

          public void Func()

                                                                                                                    Das Objekt erhält beim Kompilieren einen Fehler: Der Typ B muss über einen öffentlichen Konstruktor ohne Parameter verfügen, um ihn als Parameter „T“ im generischen Typ oder der generischen Methode C verwenden zu können.

Hinweis: C# unterstützt jetzt nur no- Einschränkungen des Parameterkonstruktors

Da wir zu diesem Zeitpunkt einen parametrisierten Konstruktor für Typ B geschrieben haben, verhindert dies, dass das System automatisch einen Parameterlosen Konstruktor für B erstellt. Wenn wir jedoch einen Parameterlosen Konstruktor zum B-Typ hinzufügen, Die Instanziierung von Objekt d meldet keinen Fehler. Der B-Typ ist wie folgt definiert:

Klasse B

{

public B()

{ }

public B(int i)

{ }

     }

Werttyp/Referenztyp:

öffentliche Struktur A { }

öffentliche Klasse B { }



öffentliche Klasse C ) >
C c2 = new C();

Das c2-Objekt hat beim Kompilieren einen Fehler erhalten: Der Typ „B“ muss ein nicht nullbarer Werttyp sein Verwenden Sie es als Parameter 'T' im generischen Typ oder Methor 'C'



Zusammenfassung:

1 Die generischen Funktionen von C# werden von der CLR unterstützt Es unterscheidet sich von den statischen Vorlagen, die von C++ zur Kompilierungszeit unterstützt werden, und auch von den einfachen Generika, die von Java mithilfe der „Wischmethode“ auf Compilerebene unterstützt werden.

2. Die generische Unterstützung von C# umfasst vier generische Typen: Klassen, Strukturen, Schnittstellen, Delegaten und Methodenmitglieder.

3. Die Generika von C# verwenden die Einschränkungsmethode „Basisklasse, Schnittstelle, Konstruktor, Werttyp/Referenztyp“, um „explizite Einschränkungen“ für Typparameter zu implementieren. Es werden keine C++-Vorlagen unterstützt Einschränkungen.

Das Obige ist der Inhalt der generischen C#-Programmierung. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Active Directory mit C# Active Directory mit C# Sep 03, 2024 pm 03:33 PM

Leitfaden zu Active Directory mit C#. Hier besprechen wir die Einführung und die Funktionsweise von Active Directory in C# sowie die Syntax und das Beispiel.

Zufallszahlengenerator in C# Zufallszahlengenerator in C# Sep 03, 2024 pm 03:34 PM

Leitfaden zum Zufallszahlengenerator in C#. Hier besprechen wir die Funktionsweise des Zufallszahlengenerators, das Konzept von Pseudozufallszahlen und sicheren Zahlen.

C#-Datenrasteransicht C#-Datenrasteransicht Sep 03, 2024 pm 03:32 PM

Leitfaden zur C#-Datenrasteransicht. Hier diskutieren wir die Beispiele, wie eine Datenrasteransicht aus der SQL-Datenbank oder einer Excel-Datei geladen und exportiert werden kann.

Zugriffsmodifikatoren in C# Zugriffsmodifikatoren in C# Sep 03, 2024 pm 03:24 PM

Leitfaden zu den Zugriffsmodifikatoren in C#. Wir haben die Einführungstypen von Zugriffsmodifikatoren in C# zusammen mit Beispielen und Ausgaben besprochen.

C#-Serialisierung C#-Serialisierung Sep 03, 2024 pm 03:30 PM

Leitfaden zur C#-Serialisierung. Hier besprechen wir die Einführung, die Schritte des C#-Serialisierungsobjekts, die Funktionsweise bzw. das Beispiel.

Muster in C# Muster in C# Sep 03, 2024 pm 03:33 PM

Leitfaden zu Mustern in C#. Hier besprechen wir die Einführung und die drei wichtigsten Arten von Mustern in C# zusammen mit ihren Beispielen und der Code-Implementierung.

Primzahlen in C# Primzahlen in C# Sep 03, 2024 pm 03:35 PM

Leitfaden zu Primzahlen in C#. Hier besprechen wir die Einführung und Beispiele von Primzahlen in C# sowie die Codeimplementierung.

Fakultät in C# Fakultät in C# Sep 03, 2024 pm 03:34 PM

Leitfaden zur Fakultät in C#. Hier diskutieren wir die Einführung in die Fakultät in C# zusammen mit verschiedenen Beispielen und Code-Implementierungen.

See all articles