vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Zippen wie die Profis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2018
 
zurück
Rubrik: Verschiedenes / Sonstiges   |   VB-Versionen: VB2005, VB200805.06.08
Extension Methods

Übersicht über die Wirkungen der Compilerdirektive "Extension"

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  9.883 
ohne HomepageSystem:  Win2k, WinXP, Vista, Win7, Win8, Win10kein Beispielprojekt 

Visual Basic 2008 introduces extension methods, which enable developers to add custom functionality to data types that are already defined without creating a new derived type. Extension methods make it possible to write a method that can be called as if it were an instance method of the existing type. (VB-Doku).

Bei diesen sogenannten "Extension Methods" handelt es sich um eine neue Compilerdirektive (in System.Runtime.CompilerServices). In (Standard-) Modulen deklarierte Subs und Functions, die mindestens einen Parameter besitzen, können anhand des Typs ihres ersten Parameters an Variable dieses Typs 'angeheftet' ('pinned', 'attached') werden. (Diese Bezeichnung entspricht eher der Wirkung der Direktive als der Begriff Erweiterung.)

Im Quellcode und in der Intellisense der IDE erscheinen solche Subs/Functions, als wären es Methoden des Parameter-Typs. (In der Intellisense wird vorangestellt). Der Debugger bezeichnet die 'Extensions' als 'Member'.

Unzulässig für den ERSTEN Parameter einer als "Extension" vorgesehenen Routine sind:

  • als Optional deklarierte Parameter;
  • als ParamArray deklarierte Parameter (weil automatisch optional).

Gebraucht wird so etwas für LINQ - die Compilerdirektive "Extension" ist aber in VB-Modulen für Subs und Functions allgemein anwendbar.

Werfen wir also einen Blick auf die Neuheit:
Da die Compilerdirektive 'Extension' mit 'Vererbung' oder ähnlichem nichts zu tun hat, lässt sie sich auf (fast) alle Objekte anwenden, die als Parameter in einer Sub/Function-Deklaration erscheinen können. Routinen, die in einem Modul vereinbart worden sind, können z.B. auch an integrierte VB-Datentypen (z.B. Integer, String), an Delegaten oder an Steuerelemente geheftet werden.

Um keine Verwirrung herbeizuführen, sollte man bei der Namensgebung für derartige Pin-Routinen auf eine einheitliche Konvention achten, z.B. "PF_"<name> für angeheftete Funktionen und "PS_"<name> für "pinned" Subs.

Die "Extension Methods" können im Code nach wie vor wie 'gewöhnliche' Subs/Functions aufgerufen werden. Es ist deshalb möglich, die Direktive noch nachträglich in den Code einzufügen. Bereits bestehende Aufrufe müssen (meist?) nicht angepasst werden.

Durch die Verwendung der Direktive ändern sich die Zugriffsbeschränkungen für die 'echten' Methoden des verwendeten Typs nicht. Z.B. sind als 'Private' deklarierte Eigenschaften oder Methoden eines Objekts in den "Extension Methods" nicht verfügbar.

Die angehefteten Routinen besitzen NICHT die Fähigkeit, gleichnamige Methoden oder Eigenschaften eines Objekts (mit gleicher Signatur) zu überschreiben oder abzuschatten (kein "Shadowing"). In solchen Fällen werden sie nicht 'angeheftet', sondern stillschweigend ignoriert. Es kommt nicht zu einem Compiler- oder Laufzeitfehler. Auch aus diesem Grund sollte man die oben vorgeschlagene Namenskonvention einhalten, damit es nicht zu Namensüberschneidungen kommt.

Durch das Anheften verändern die Routinen ihren Geltungsbereich nicht. Als 'Private' deklarierte Routinen sind auch nach ihrer "Erweiterung" nur innerhalb ihres Moduls verfügbar. Gewöhnlich werden solche Routinen als 'Friend' oder 'Public' eingerichtet.

Vorsicht ist geboten bei Verwendung "unspezifischer" Datentypen als erste Parameter (z.B. 'As Object', As 'System.Array').

Wenn in der Signatur einer Routine ein Parameter 'As Object' verwendet wird, erfolgt in deren Code meist zunächst eine Abfrage des übergebenen Datentyps und - je nach Typ - werden spezifische Anweisungen ausgeführt. Bei Übergabe eines nicht unterstützten Typs wird abgebrochen.

Parameter vom Typ 'As Object' sind auch als erste Parameter für 'Extension Methods' zugelassen. In dem Fall heftet sich die Routine an alles, was möglich und erreichbar ist. Das gilt z.B. auch für Parameter, die als 'As System.Array' vereinbart sind. In dem Fall heftet sich die Routine an alle Arrays.

Falls ein derart allgemeiner Parameter 'ByRef' deklariert worden ist, kommt es zu Laufzeitfehlern, wenn der beim Aufruf verwendete Typ nicht mit dem Typ der Rückgabe korrespondiert. Die VB-Dokumentation empfiehlt deshalb, immer einen möglichst spezifischen Typ zu verwenden bzw. einen Typ, von dem nicht abgeleitet worden ist.

Der Compiler wertet für die Festlegung, wo eine Routine angeheftet werden soll, nur den ersten Parameter aus. Der Typ dieses Parameters darf deshalb nicht von anderen Parametern in der Signatur in irgendeiner Form abhängig sein (z.B. durch sog. 'Constraints').

Die Compilerdirektive kann auch auf Überladungen angewendet werden.

Wird die Überladung durch den ersten Parameter bewirkt, heften sich die überladenen Funktionen an verschiedene Typen. Wird die Überladung nicht durch den ersten Parameter bewirkt, heften sich alle überladenen Funktionen an den Typ, der im ersten Parameter verwendet worden ist. Damit dies geschieht, muss allerdings jede einzelne der Überladungs- Routinen mit der Compilerdirektive ausgerüstet werden. Die selektive Verwendung der Direktive ist möglich.

Rekursive Aufrufe von 'Extension Methods' sind zugelassen. Man kann z.B. innerhalb einer 'Extension Method' auf die entsprechende 'Extension Method' des rufenden Objekts - das als erster Parameter übergeben wird -, zugreifen. Eine Endlos-Rekursion droht.

Bei der Verwendung eines Objekts innerhalb eines anderen Objekts stehen die 'Extension Methods' des eingebauten Objekts zur Verfügung (falls sie 'in Scope' sind; d.h. die Module müssen ggf. importiert werden). Dadurch wird das umschließende Objekt von den Modulen anhängig, in denen diese Routinen deklariert sind.

Die VB-Dokumentation bezeichnet "extension methods" als "a convenient and powerful way to extend an existing type." Unmittelbar danach listet sie allerdings Beispiele dafür auf, wie "vulnerable" komplexere Projekte - insbesondere Bibliotheken - durch die Verwendung dieser Compilerdirektive werden. Die dort genannten Vorschläge ("some points to consider") für 'best practices' sind 'best'enfalls 'Krücken' um die Wahrscheinlichkeit von Konflikten zu reduzieren - immerhin Konflikte, von denen manche weder beim Kompilieren noch zur Laufzeit erkennbar werden.

Werden gleichnamige Extension Methods in verschiedenen Kontexten deklariert, verwendet der Compiler ggf. eine umfangreiche Hierarchie, um zu entscheiden, welche der zur Verfügung stehenden Routinen im Einzelfall aufgerufen wird. Die Dokumentation empfiehlt, im Zweifelsfall die angehefteten Routinen im Code 'voll qualifiziert' - also auf herkömmliche Weise - aufzurufen.

'Extension Methods' sollte man - wenn überhaupt - möglichst sparsam und eindeutig benannt einsetzen.

Dieser Tipp wurde bereits 9.883 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2018 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel