C# 2.0-Spezifikation (anonyme Methode) (2)
21.7 Delegateninstanzgleichheit
Die folgenden Regeln gelten für Ergebnisse, die vom Gleichheitsoperator (§7.9.8) und der Methode „object.Equals“ anonymer Methodendelegateninstanzen erzeugt werden.
l Wenn Delegateninstanzen aus der Auswertung semantisch identischer anonymer Methodenausdrücke mit demselben Satz erfasster externer Variablen resultieren, gelten sie als gleich (müssen aber nicht sein).
l Wenn Delegateninstanzen durch anonyme Methodenausdrücke mit unterschiedlicher Semantik oder mit unterschiedlichen Sätzen erfasster externer Variablen dargestellt werden, sind sie niemals gleich.
21.8 Explizite Zuweisung
Der explizite Zuweisungsstatus anonymer Methodenparameter ist der gleiche wie der benannter Methoden. Das heißt, Referenzparametern und Wertparametern werden explizit Anfangswerte zugewiesen, während Ausgabeparametern keine Anfangswerte zugewiesen werden müssen. Außerdem müssen Ausgabeparameter explizit zugewiesen werden, bevor die anonyme Methode normal zurückkehrt (§5.1.6).
Wenn die Steuerung an den Programmblock des anonymen Methodenausdrucks übergeben wird, ist der explizite Zuweisungsstatus der externen Variablen v derselbe wie der explizite Zuweisungsstatus von v vor dem anonymen Methodenausdruck. Das heißt, explizite Zuweisungen an externe Variablen werden vom Kontext des anonymen Methodenausdrucks geerbt. Innerhalb anonymer Methodenblöcke werden explizite Zuweisungen wie innerhalb gewöhnlicher Blöcke abgeleitet (§5.3.3).
Der explizite Zuweisungsstatus der Variablen v nach dem anonymen Methodenausdruck ist derselbe wie ihr expliziter Zuweisungsstatus vor dem anonymen Methodenausdruck.
Beispielsweise generiert
delegate bool Filter(int i); void F() { int max; // 错误,max没有明确赋值 Filter f = delegate(int n) { return n < max; } max = 5; DoWork(f); }
einen Fehler bei der Kompilierung, da max nicht explizit dort zugewiesen wird, wo die anonyme Methode deklariert ist. Beispiel
delegate void D(); void F() { int n; D d = delegate { n = 1; }; d(); //错误,n没有明确赋值 Console.WriteLine(n); }
generiert ebenfalls einen Fehler bei der Kompilierung, da die Zuweisung von n innerhalb der anonymen Methode keinen Einfluss auf den expliziten Zuweisungsstatus von n außerhalb der anonymen Methode hat.
21.9 Methodengruppenkonvertierung
Ähnlich wie bei der in §21.3 beschriebenen impliziten anonymen Methodenkonvertierung gibt es auch eine implizite Konvertierung von einer Methodengruppe (§7.1) in einen kompatiblen Delegattyp Konvertieren.
Wenn für eine gegebene Methodengruppe E und einen Delegatentyp D Delegatenerstellungsausdrücke der Form „new D(E)“ zulässig sind (§7.5.10.3 und §20.9.6), dann gibt es einen impliziten Pfad von E nach D Konvertierung, und das Ergebnis der Konvertierung entspricht genau dem neuen D(E).
Im folgenden Beispiel erstellt der Konstruktor
using System; using System.Windows.Forms; class AlertDialog { Label message = new Label(); Button okButton = new Button(); Button cancelButton = new Button();` public AlertDialog() { okButton.Click += new EventHandler(OkClick); cancelButton.Click += new EventHandler(CancelClick); ... } void OkClick(object sender, EventArgs e) { ... } void CancelClick(object sender, EventArgs e) { ... } }
zwei Delegateninstanzen mit new. Implizite Methodengruppenkonvertierungen ermöglichen eine Vereinfachung auf
public AlertDialog() { okButton.Click += OkClick; cancelButton.Click += CancelClick; ... }
Wie bei allen anderen impliziten und expliziten Konvertierungen können Konvertierungsoperatoren verwendet werden, um eine bestimmte Konvertierung explizit durchzuführen. Dazu kann das Beispiel
object obj = new EventHandler(myDialog.OkClick);
stattdessen wie folgt geschrieben werden.
object obj = (EventHandler)myDialog.OkClick;
Anonyme Methodenausdrücke der Methodenzusammensetzung können die Überladungsauflösung beeinflussen, sind jedoch nicht an der Typinferenz beteiligt. Weitere Einzelheiten finden Sie in §20.6.4.
21.10 Implementierungsbeispiel
In diesem Abschnitt werden mögliche Implementierungen anonymer Methoden in Form von Standard-C#-Komponenten beschrieben. Die hier beschriebene Implementierung basiert auf denselben Prinzipien, die auch der Microsoft C#-Compiler verwendet, ist jedoch keineswegs obligatorisch oder die einzig mögliche Implementierung.
Der letzte Teil dieses Abschnitts enthält mehrere Beispielcodes, die anonyme Methoden mit unterschiedlichen Eigenschaften enthalten. Für jedes Beispiel stellen wir eine entsprechende Transformation des Codes mithilfe eines eindeutigen Standard-C#-Konstrukts bereit. In diesen Beispielen wird davon ausgegangen, dass der Bezeichner D den folgenden Delegatentyp darstellt.
public delegate void D();
Die einfachste Form einer anonymen Methode ist die, die keine externen Variablen erfasst.
class Test { static void F() { D d = delegate { Console.WriteLine("test"); }; } }
Dieser Code kann in eine Delegate-Instanz konvertiert werden, die auf eine vom Compiler generierte statische Methode verweist, und der Code der anonymen Methode wird in die statische Methode eingefügt. ,
class Test { static void F() { D d = new D(__Method1); } static void __Method1() { Console.WriteLine("test"); } }
Im folgenden Beispiel verweist die anonyme Methode auf das Instanzmitglied davon.
class Test { int x; void F() { D d = delegate { Console.WriteLine(x); }; } }
Dies kann in eine vom Compiler generierte Instanzmethode konvertiert werden, die anonymen Methodencode enthält.
class Test { int x; void F() { D d = new D(__Method1); } void __Method1() { Console.WriteLine(x); } }
In diesem Beispiel erfasst die anonyme Methode eine lokale Variable.
class Test { void F() { int y = 123; D d = delegate { Console.WriteLine(y); }; } }
该局部变量的生存期现在至少必须延长到匿名方法委托的生存期为止。这可以通过将局部变量“提升(lifting)”为编译器生成的(compiler-generated)类的字段来完成。局部变量的实例化对应于创建一个编译器生成的类的实例,而访问局部变量将对应于访问编译器生成的类实例的一个字段。并且,匿名方法将成为编译器生成类的实例方法。
class Test { void F() { __locals1 = new __Locals1(); __locals1.y = 123; D d = new D(__locals1.__Method1); } class __Locals1 { public int y; public void __Method1() { Console.WriteLine(y); } } }
最后,如下匿名方法将捕获this,以及具有不同生存期的两个局部变量。
class Test { int x; void F() { int y = 123; for (int i = 0; i < 10; i++) { int z = i * 2; D d = delegate { Console.WriteLine(x + y + z); }; } } }
在这里,编译器将为每个语句块生成类,在这些语句块中局部变量将被捕获,而在不同块中的局部变量将会有独立的生存期。
__Locals2的实例,编译器为内部语句块生成的类,包含局部变量z和引用__Locals1实例的字段。__Locals1的实例,编译器为外部语句块生成的类,包含局部变量y和引用封闭函数成员的this的字段。通过这些数据结构,你可以通过__Locals2的一个实例到达所有被捕获的局部变量,并且匿名方法的代码可以作为那个类的实例方法而实现。
class Test { void F() { __locals1 = new __Locals1(); __locals1.__this = this; __locals1.y = 123; for (int i = 0; i < 10; i++) { __locals2 = new __Locals2(); __locals2.__locals1 = __locals1; __locals2.z = i * 2; D d = new D(__locals2.__Method1); } } class __Locals1 { public Test __this; public int y; } class __Locals2 { public __Locals1 __locals1; public int z; public void __Method1() { Console.WriteLine(__locals1.__this.x + __locals1.y + z); } } }
(匿名方法完)
以上就是C# 2.0 Specification(匿名方法)(二)的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Die Nutzungsmethoden von Symbolen in der C-Sprachabdeckung Arithmetik, Zuordnung, Bedingungen, Logik, Bitoperatoren usw. werden für grundlegende mathematische Operationen verwendet, Zuordnungsoperatoren werden zur Zuordnung und Addition verwendet, Subtraktion, Multiplikationszuordnung und Abteilungszuweisung, Zustandsbetreiber werden für Unterschiede verwendet. Logische Operationen werden verwendet. Logische Operationen werden verwendet. Logische Operationen werden verwendet. Zeiger, Markierungen am Ende der Datei und nicht numerische Werte.

In C wird der Zeichenentyp in Saiten verwendet: 1. Speichern Sie ein einzelnes Zeichen; 2. Verwenden Sie ein Array, um eine Zeichenfolge darzustellen und mit einem Null -Terminator zu enden. 3. Durch eine Saitenbetriebsfunktion arbeiten; 4. Lesen oder geben Sie eine Zeichenfolge von der Tastatur aus.

In der C -Sprache werden Sonderzeichen durch Escape -Sequenzen verarbeitet, wie z. B.: \ n repräsentiert Linienbrüche. \ t bedeutet tab charakter. Verwenden Sie Escape -Sequenzen oder Zeichenkonstanten, um Sonderzeichen darzustellen, wie z. B. char c = '\ n'. Beachten Sie, dass der Backslash zweimal entkommen muss. Verschiedene Plattformen und Compiler haben möglicherweise unterschiedliche Fluchtsequenzen. Bitte wenden Sie sich an die Dokumentation.

Der Unterschied zwischen Multithreading und Asynchron besteht darin, dass Multithreading gleichzeitig mehrere Threads ausführt, während asynchron Operationen ausführt, ohne den aktuellen Thread zu blockieren. Multithreading wird für rechenintensive Aufgaben verwendet, während asynchron für die Benutzerinteraktion verwendet wird. Der Vorteil des Multi-Threading besteht darin, die Rechenleistung zu verbessern, während der Vorteil von Asynchron nicht darin besteht, UI-Threads zu blockieren. Die Auswahl von Multithreading oder Asynchron ist von der Art der Aufgabe abhängt: Berechnungsintensive Aufgaben verwenden Multithreading, Aufgaben, die mit externen Ressourcen interagieren und die UI-Reaktionsfähigkeit asynchron verwenden müssen.

In der C -Sprache ist der Hauptunterschied zwischen char und wchar_t die Zeichencodierung: char verwendet ASCII oder erweitert ASCII, wchar_t Unicode; char nimmt 1-2 Bytes auf, wchar_t nimmt 2-4 Bytes auf; char ist für englischen Text geeignet. Wchar_t ist für mehrsprachige Text geeignet. char ist weithin unterstützt, wchar_t hängt davon ab, ob der Compiler und das Betriebssystem Unicode unterstützen. char ist in der Charakterbereich begrenzt, WCHAR_T hat einen größeren Charakterbereich und spezielle Funktionen werden für arithmetische Operationen verwendet.

In der C -Sprache kann die char -Typ -Konvertierung direkt in einen anderen Typ konvertiert werden, wenn: Casting: Verwenden von Casting -Zeichen. Automatische Konvertierung des Typs: Wenn ein Datentyp einen anderen Werttyp berücksichtigen kann, wandelt der Compiler diese automatisch um.

Es gibt keine integrierte Summenfunktion in der C-Sprache, daher muss sie selbst geschrieben werden. Die Summe kann erreicht werden, indem das Array durchquert und Elemente akkumulieren: Schleifenversion: Die Summe wird für die Schleifen- und Arraylänge berechnet. Zeigerversion: Verwenden Sie Zeiger, um auf Array-Elemente zu verweisen, und eine effiziente Summierung wird durch Selbststillstandszeiger erzielt. Dynamisch Array -Array -Version zuweisen: Zuordnen Sie Arrays dynamisch und verwalten Sie selbst den Speicher selbst, um sicherzustellen, dass der zugewiesene Speicher befreit wird, um Speicherlecks zu verhindern.

Das Char -Array speichert Zeichensequenzen in der C -Sprache und wird als char Array_name [Größe] deklariert. Das Zugriffselement wird durch den Einweisoperator weitergeleitet, und das Element endet mit dem Null -Terminator '\ 0', der den Endpunkt der Zeichenfolge darstellt. Die C -Sprache bietet eine Vielzahl von String -Manipulationsfunktionen wie Strlen (), Strcpy (), Strcat () und strcmp ().
