2013-07-24 28 views
8
using System; 

class Runner 
{ 
    static void Main() 
    { 
     A a = new A(); 
     // how to say a.PrintStuff() without a 'using' 
     Console.Read(); 
    } 
} 

class A { } 

namespace ExtensionMethod 
{ 
    static class AExtensions 
    { 
     public static void PrintStuff(this A a) 
     { 
      Console.WriteLine("text"); 
     } 
    } 
} 

Wie würde ich die Erweiterungsmethode ohne ein "verwenden" aufrufen? Und nicht ExtensionMethod.AExtensions.PrintStuff (a), da die Erweiterungsmethode nicht verwendet wird.So rufen Sie eine Erweiterungsmethode ohne Verwendung von

+6

Warum möchten Sie eine using-Anweisung hinzufügen? –

+0

Mit Ihrem Code wie es ist, können Sie nicht. Es tut uns leid. Der C# -Compiler muss wissen, wo die Erweiterungsmethode zu finden ist. Wenn es sich in einem separaten Namespace befindet, brauchen Sie das 'using', nicht herum. – rossipedia

+0

Ich nehme an, Sie können möglicherweise die statische Erweiterungsmethode manuell aufrufen und das Objekt als erstes Argument übergeben, aber das wäre kaum eine Verbesserung gegenüber dem Import des Namespace. – David

Antwort

5

Es braucht die using zu wissen, wo die Funktion lebt. Ein Beispiel dafür in Linq. Ohne das System.Linq verwenden - Sie haben keine linq aktiviert für IEnumerable<T>' s

Sie können jedoch die Erweiterungsmethode im gleichen Namespace wie der Aufrufer definieren, um eine Verwendung zu vermeiden. Dieser Ansatz funktioniert jedoch nicht, wenn es in vielen Namensräume

11

benötigt wird, was möglich ist, wenn Erweiterungsmethode und Klasse A in gleichen Namensraum,

Wenn Sie verschiedene Namensräume verwenden müssen, dann müssen Sie using verwenden, i don‘ Ich denke, es gibt einen Weg, dies ohne using zu tun. Sie können jedoch die Anzahl der using reduzieren, indem man alle Erweiterungen wie für Linq in einem Namensraum setzen (System.Linq.Extensions)

Hinweis: Sie können den Namespace für Erweiterungsmethoden entfernen, dann wird es sie global verfügbar machen

+5

+1 für die "Note", sehr gute Idee. –

+2

wusste nicht einmal, dass der Namespace nicht benötigt wurde :) –

3

Das macht mich schmutzig, aber Sie können Ihre Erweiterungsmethoden in den Namensraum System einfügen. Dieser Namespace ist standardmäßig in Ihrer Frage enthalten

using System; 

class Runner 
{ 
    static void Main() 
    { 
     A a = new A(); 
     // how to say a.PrintStuff() without a 'using' 
     Console.Read(); 
    } 
} 

class A { } 

namespace System 
{ 
    static class AExtensions 
    { 
     public static void PrintStuff(this A a) 
     { 
      Console.WriteLine("text"); 
     } 
    } 
} 
2

Ruminations auf die Schaffung von Erweiterungsmethoden für einen Typ ExtendableType:

  • Namen der Klasse ExtendableTypeExtensions
  • die Erweiterung Klasse Deklarieren teilweise, damit Clients Erweiterungsmethoden nach dem gleichen Muster hinzufügen können; und
  • Setzen Sie die Erweiterungsmethoden im gleichen Namensraum als Basistyp

es sei denn Sie einen sehr guten Grund haben, ein Modell wie das von LINQ zu folgen:

  • Ein wesentlicher Familie der Erweiterungsmethoden,
  • Das alles gilt für mehrere Basisklassen.
0

In unseren Projekten werden Erweiterungen im selben Namespace platziert wie die Klassenerweiterung für. Ihr Beispiel:

A.cs: 
using System; 
namespace ANamespace 
{ 

    class A { } 
} 

AExtensions.cs: 
namespace ANamespace 
{ 
    static class AExtensions 
    { 
     public static void PrintStuff(this A a) 
     { 
      Console.WriteLine("text"); 
     } 
    } 
} 

Wenn Sie jetzt using für ANamespace hinzufügen für die Verwendung der A Klasse, alle Erweiterungen für A Klasse wird auch enthalten sein.

8

Es ist möglich, Ihre Erweiterung direkt wie so zu nennen, da es einfach eine statische Methode ist, wird die Instanz, der sie weiter als erste this Parameter handeln:

A a = new A(); 
ExtensionMethod.AExtensions.PrintStuff(a); 

Dies könnte an andere Entwickler verwirrend sein, über diesen Code geschehen, wenn Sie dieses Muster für häufiger verwendete Erweiterungsmethoden befolgt haben. Es würde auch dazu führen, dass Verkettungsverlängerungsanrufe wie LINQ mehr wie eine funktionale Sprache erscheinen, weil Sie jeden Anruf verschachteln würden, anstatt ihn zu verketten.

+0

Diese Methode funktioniert hervorragend, wenn Sie keinen Namespace importieren möchten, der viele Kollisionen mit anderen Namespaces aufweist, die Sie bereits importiert haben. – humbads

Verwandte Themen