2008-11-26 11 views
20

Ich habe in letzter Zeit ziemlich viele Erweiterungsmethoden verwendet und habe viele Verwendungsmöglichkeiten für sie gefunden. Das einzige Problem, das ich habe, ist zu erinnern, wo sie sind und welchen Namespace zu verwenden, um die Erweiterungsmethoden zu erhalten.Ist es in Ordnung, meine eigenen Erweiterungsmethoden im Systemnamensraum zu schreiben?

Allerdings hatte ich vor kurzem einen Gedanken über das Schreiben der Erweiterungsmethoden im System-Namespace, System.Collections-Namespace oder einem anderen System-Namespace, der Sinn macht. So habe ich zum Beispiel Folgendes implementiert.

namespace System 
{ 
    /// <summary>Various array extensions</summary> 
    public static class ArrayExtensions 
    { 
     /// <summary>Converts the array to a hex string</summary> 
     /// <param name="value">The value.</param> 
     /// <returns>The array as a hex string</returns> 
     public static string ToHexString(this byte[] value) 
     { 
      var hex = new StringBuilder(value.Length * 2); 
      foreach (byte b in value) 
      { 
       hex.AppendFormat("{0:X2}", b); 
      } 
      return hex.ToString(); 
     } 
    } 
} 

Ist das die richtige Entscheidung?

Antwort

22

Aus dem Framework Design Guidelines (2nd Edition):

NICHT Erweiterungsmethoden im gleichen Namensraum wie die erweiterte Art setzen, es wäre denn, es für das Hinzufügen von Methoden zu Schnittstellen ist, oder für Abhängigkeitsmanagement.

Während dies Ihr Szenario nicht explizit behandelt, sollten Sie es im Allgemeinen vermeiden, einen Framework-Namespace (oder einen Namespace, den Sie nicht kontrollieren) zu erweitern und stattdessen diese Erweiterungen in ihren eigenen Namespace zu stellen. Wenn Sie das Gruppieren der Erweiterungen stark bevorzugen (so dass die Sammlungserweiterungen zusammen sind, usw.), könnten Sie einen Subnamespace einführen. In Ihrem Szenario würde die Erweiterung der Sammlungen in einen System.Collection.Extensions Namespace oder einen Company.Collections oder sogar einen Company.Collections.Extension Namespace gehen.

Um Erweiterungsmethoden zu verwenden, muss der Namespace importiert werden, der die Sponsor-Klasse enthält (die Klasse, die die Erweiterungsmethoden definiert). Wenn Sie einem der standardmäßigen .NET Framework-Namespaces Erweiterungsmethoden hinzufügen, sind diese immer (und implizit) verfügbar.

14

Sie sollten es vermeiden, Namespaces zu erweitern, über die Sie keine primäre Kontrolle haben, da zukünftige Änderungen Ihren Code beschädigen können (z. B. durch die Einführung von Duplikaten).

Ich neige dazu, die Standard-Namespaces mit einem anderen Stammnamespace nachzuahmen, der alle untergeordneten Namespaces als zu meiner Arbeit gehörend identifiziert. Der Root-Namespace könnte Ihr Name, der Name Ihrer Organisation oder etwas anderes sein, das den Inhalt dieses Namespace als Ihren identifiziert. Wenn Sie beispielsweise System.Collections erweitern möchten, können Sie NickR.Collections oder NickR.System.Collections verwenden.

3

Nicht sicher, ob es falsch ist (oder richtig, in der Tat), aber warum nicht Ihren eigenen Namensraum "Erweiterungen" haben? Dann lege alle Erweiterungsmethoden in diesen Namespace und sei konsistent.

Ich glaube nicht, das eigentliche Problem ist, wo sie oder was es benennen (System oder einen anderen Namespace), aber konsistent sein und immer dasselbe verwenden, um Ihr Problem zu vermeiden (vergessen, wo sie sind).

0

Ich lege meine Erweiterungsmethoden in einen Namensraum, abhängig von der Sichtbarkeit, die ich haben möchte. Auf diese Weise sind sie leichter zu entdecken und ich bekomme normalerweise weniger Namespace-Importe.

4

Die einzige Sache, die der Namespace mit Erweiterungsmethoden wirklich beeinflusst, ist Sichtbarkeit und Auffindbarkeit - also hängt es davon ab, ob die Erweiterungsmethoden immer auf diesem Typ erscheinen sollen oder nicht. Die Framework-Design-Richtlinien sind in erster Linie für öffentliche APIs gedacht, und obwohl es im Allgemeinen eine gute Idee ist, ihnen zu folgen, sind die Regeln für interne APIs sehr gut zu durchbrechen, wenn es sinnvoll ist.

Zum Beispiel haben wir eine Menge Arbeit mit TimeSpan Objekten in der gesamten Codebasis und es gibt keine Methoden, um diese im Rahmen zu multiplizieren oder dividieren, so dass wir MultiplyBy und DivideBy Erweiterungsmethoden hinzugefügt haben, unter anderem, und legt sie in dem System Namensraum, weil wir sie zugänglich und auffindbar wollen, wo immer TimeSpan verwendet wird.

Auf der anderen Seite haben wir auch ziemlich viel Reflexion Arbeit, auf Type Objekte arbeiten, und es gibt eine ganze Reihe von Erweiterungsmethoden, die in bestimmten Bereichen sehr nützlich sind, aber nicht im Allgemeinen, so dass diese leben in einem OurCompany.Reflection Namespace also müssen sie speziell importiert werden.

So läuft die Entscheidung für interne APIs auf "Soll ich diese Methode überall verfügbar sein, wo der Typ in unserer Codebasis verfügbar ist?". Wenn die Antwort ja ist, dann lege sie in den gleichen Namensraum, sonst lege sie woanders hin.

Verwandte Themen