2008-11-02 8 views
13

Ich habe eine Klasse, die einen CallRate-Typ definiert. Ich muss die Möglichkeit hinzufügen, mehrere Instanzen meiner Klasse zu erstellen, indem ich die Daten aus einer Datei lese.Sollte eine C# -Klasse Instanzen von sich selbst generieren?

Ich habe meiner Klasse CallRate eine statische Methode hinzugefügt, die eine List<CallRate> zurückgibt. Ist es in Ordnung, wenn eine Klasse neue Instanzen von sich selbst generiert, indem sie einen eigenen Konstruktor aufruft? Es funktioniert, ich frage mich nur, ob es das Richtige ist.

List<CallRates> cr = CallRates.ProcessCallsFile(file); 

Antwort

20

Es ist vollkommen in Ordnung, Objekte aus der statischen Methode zu erhalten.

z.B.

Einer der dot net Bibliotheken macht das Gleiche wie du,

XmlReadrer reader = XmlReader.Create(filepathString); 
+0

Das wird das Fabrikmuster genannt, wenn ich mich nicht irre und wie gesagt, eine vollkommen lebensfähige Methode ist, diese Aufgabe zu erfüllen. Ich bevorzuge es im Allgemeinen, die Fabrik von der Klasse getrennt zu halten, aber das hängt weitgehend von den persönlichen Vorlieben ab. –

+0

Es gibt zwei Arten von Factory (in GoF-Buch): Abstract Factory und Factory-Methode. Die vorgestellte Methode ist ein Beispiel für eine Factory-Methode. –

+0

Ja, das Fabrikmuster in der Tat. –

2

Scheint mir gut. In anderen Sprachen würden Sie wahrscheinlich eine Funktion schreiben, aber in einer Sprache wie C# übernehmen statische Methoden diese Rolle.

1

Es ist in Ordnung. Was Sie gerade erstellt haben, ist so etwas wie eine einfache Fabrikmethode. Sie haben eine statische Methode, die eine gültige Instanz eines Typs erstellt. Eigentlich muss Ihre Methode nicht einmal statisch sein und Sie haben immer noch einen gültigen Code. Es gibt ein Entwurfsmuster (Prototyp), das ein neues gültiges Objekt aus einem vorhandenen Objekt erstellt. Siehe Details unter http://www.dofactory.com/Patterns/PatternPrototype.aspx.

+0

Ich brauchte einen guten Grund, um Klassenmuster zu lernen. Vielen Dank. – user10178

1

Sicher, für einfache Analyse (oder ähnliche) Szenarien - ich eigentlich bevorzugen die factory method Teil der Klasse sein. Ja - es bricht SRP, aber es erfüllt KISS - so nenne ich es einen Nettogewinn. Bei größeren Apps oder komplizierteren Parseroutinen ist es sinnvoller, wenn es sich um eine externe Factory-Klasse handelt. Für Ihren speziellen Fall würde ich wahrscheinlich eine Methode bevorzugen, die eine IEnumerable <Zeichenkette> anstelle eines Dateinamens - das würde Ihnen immer noch die Parsing-Logik, sondern ermöglichen einfache Unit-Tests und "Wiederverwendung". Der Aufrufer kann die Datei problemlos in ein IEnumerable umbrechen.

1

Fabrik Methoden sind oft ein gutes Design. Als ich sie in C# zu schreiben, ich nenne sie 'Neu', so dass:

new MyClass() 

wird

MyClass.New() 

Trivial es so implementiert ist:

class MyClass 
{ 
    public static MyClass New() 
    { 
     return new MyClass(); 
    } 
} 

Meistens mache ich das, wenn Es gibt zusätzliche Bedingungen darüber, ob die Klasse tatsächlich erstellt werden soll oder ob nur null zurückgegeben wird oder ob MyClass oder etwas davon zurückgegeben wird.

+0

Muss für Leute, die an VB.Net gewöhnt sind, verwirrend sein. In VB.Net heißt der Konstruktor "Neu". – Kibbee

+0

Vielleicht; oder vielleicht macht es einen guten Sinn - denken Sie an es als ein statisches ctor gegen eine Instanz ctor oder etwas. Das kann ich nicht wirklich sagen, da ich nicht viel Zeit mit VB.NET-Programmierern verbracht habe. –

1

Ich benutze manchmal öffentliche statische Methoden als eine Alternative zum Überladen von Konstruktoren.

Insbesondere in Situationen, in denen es nicht schön ist, sich allein auf Parametertypen zu verlassen, um anzuzeigen, welche Art von Objektkonstruktion beabsichtigt ist.

1

Ich bin ein Fan von statischen Methoden, die Instanzen zurückgeben, wie oft vorgeschlagen, oben.

@Paul: Vergiss nicht den obigen Kommentar anzukreuzen, was du findest ist die beste Antwort.

+0

Entschuldigung! Jeder gab mir Hilfe, also gab ich alles auf. Ich habe nicht den Ruf, Ticks zu entfernen, indem ich ticke und nur einen auswähle. boneHead = ich; – user10178

+0

Sie entfernen "up-Ticks", indem Sie sie ein zweites Mal drücken. –

1

mag nur darauf hinweisen „neue Instanzen von sich selbst erzeugen, indem sie einen seiner eigenen Konstrukteuren Aufruf“

Es ist nicht von der Konstruktor, es von der statischen Methode.

+0

Ja, aber meine statische Methode ruft einen Konstruktor auf ... Ich habe das jetzt als eigene Klasse herausgebrochen. Vielen Dank. – user10178

1

Ich verwende das im Allgemeinen, wenn ich sofortige Implementierungen einer Klasse brauche. Zum Beispiel

public class Car 
    { 
     public static Car RedExpensiveCar = new Car("Red", 250000); 

     public Car() 
     { 

     } 

     public Car(string color, int price) 
     { 
      Color = color; 
      Price = price; 
     } 

     public string Color { get; set; } 
     public int Price { get; set; } 
    } 

Und mit diesem, ich brauche nicht zu erinnern oder schreiben Konstruktor Parameter in meinem Code.

Car car = Car.RedExpensiveCar; 
+0

Beachten Sie, dass in Ihrem Beispiel Auto = Car.RedExpensiveCar ist * nicht * ein neues Auto erstellen. Es wird immer dieselbe Instanz zurückgeben. Noch problematischer, da Sie ein öffentliches Feld verwenden, könnte es zugewiesen werden: Car.RedExpensiveCar = neues Auto ("Primer Brown", 75); – munificent

+0

Im Allgemeinen besser ist öffentliches statisches Auto RedExpensiveCar {get {neues Auto zurückbringen ("Rot", 250000); }} – munificent

3

Ich benutze oft dieses Muster, wenn ich die Gültigkeit der Parameter überprüfen muss. Es wird dringend davon abgeraten, eine Ausnahme von einem Konstruktor zu werfen. Es ist nicht so schlecht von einer Factory-Methode, oder Sie können wählen, null zurückzugeben.

0

Es ist durchaus akzeptabel, dies zu tun. Wenn ich das tue, mache ich normalerweise die echten Konstruktoren für die Klasse private, so dass klar ist, dass die nur Weg, Instanzen zu konstruieren, durch die statische Methode ist.

Dies ist sehr nützlich in Fällen, in denen "Konstruktion" möglicherweise nicht immer eine neue Instanz zurückgibt. Beispielsweise möchten Sie möglicherweise ein zuvor zwischengespeichertes Objekt zurückgeben.