Wie erstelle ich einen generator in C# für ein Objekt, das Eigenschaften hat, die sind referenc-Typen?

StackOverflow https://stackoverflow.com/questions/1402975

Frage

Ich habe angefangen zu bauen-generator, so dass ich problemlos erstellen von Testdaten für unit-tests, die ich Schreibe.

Die grundlegende Struktur der builder ist:

public class MyClassBuilder
{
    public int id = 0; //setting the default value here

    //allows MyClass to be built with a specific id
    public MyClassBuilder WithId(int id)
    {
        this.id = id;
        return this;
    }

    public MyClass Build()
    {
        return new MyClass(id);
    }
}

Die Verwendung dieses Muster wird dann:

MyClass mc = new MyClassBuilder().WithId(5).Build();

Ich bin gut...aber wo habe ich Fragen, ist, wenn MyClass hat eine Eigenschaft, die nicht trivial....Ich bin ein bisschen unsicher darüber, wie man konstruieren kann mit einem default-Wert.

public class MyClassBuilder
{
    public int id = 0; //setting the default value here

    //do I construct the default value using a MySecondClassBuilder?
    public MySecondClass mySecondClass;

    //allows MyClass to be built with a specific id
    public MyClassBuilder WithId(int id)
    {
        this.id = id;
        return this;
    }

    public MyClassBuilder WithMySecondClass(MySecondClass mySecondClass)
    {
        this.mySecondClass = mySecondClass;
    }

    public MyClass Build()
    {
        return new MyClass(id);
    }
}

Meine Vermutung ist, dass ich es schaffen würde, ein generator für MySecondClass und verwenden Sie, um erstellen Sie die default-Implementierung.

Kann jemand bestätigen, dass meine Annahme richtig ist und ist die beste Praxis?

Ich bin derzeit in den Prozess der Erprobung meine Annahme, aber ich dachte, ich würde Dokument diese Idee auf StackOverflow, da nur Beispiele für die builder-Muster, das ich finden konnte über google immer nur konstruiert Eigenschaften, dass sind Wert-Typen und nicht-Referenz-Typen.

War es hilfreich?

Lösung

Wie bei den meisten Dingen -. Es hängt

Wenn Sie Referenzsemantik im mySecondClass Feld wollen (dh: Sie wollen einen Verweis auf eine andere Klasse speichern), dann ist es genau wie Ihre ganze Zahl ist. der Standard null sein Having könnte durchaus akzeptabel sein.

Wenn Sie jedoch wollen immer einen Wert garantieren, werden Sie brauchen entweder zu bauen oder einfach nur ein neues Objekt für die zweite Klasse zu konstruieren.

Auch wenn Sie statt durch Verweis Kopien Klonen möchten, müssen Sie würde ein neues Objekt konstruieren und es mit dem Referenz zuweisen.

Dass gesagt wird, in vielen Fällen sind die traditionellen Konstrukteurs besser geeignet als der Versuch, eine fließende Build-Stil-Schnittstelle zu tun. Es ist wirklich einfach zu „versauen“ Fluent Interface für wie diese bauen, da man auf dem Benutzer mehr als mit einem traditionellen Konstruktor angewiesen ist.

Als Beispiel in Ihrem Code, was passiert, wenn der Benutzer nie bauen ruft? Es ist der Rückkehr noch etwas (da jede der Methoden ein Objekt zurückgibt), aber ist es gültig? Ich würde nicht als Verbraucher der Klasse sicher sein. Traditioneller Bauer mit Überlastungen, auf der anderen Seite, zeigen Sie mir genau das, was gültig ist und was nicht gültig ist, und kompiliert Zeit erzwungen.

Andere Tipps

Einmal habe ich ein Komplexes Objekt, wo ich will, einen dummy zu verwenden, in unit-tests, werde ich in der Regel drehen sich zu einem spöttischen/faking - /Lokalisierungs-framework.In C#, meine Vorliebe ist Moq, aber es gibt einige heraus dort, wie Rhino Mocks, Typemock und so auf.

Der Vorteil dort ist, dass Sie normalerweise die Fähigkeit haben, stub alle Eigenschaften, die es in der ursprünglichen Art mit default-Werten und leeren Objekten, ohne dass du nichts anderes tun, als eine single-line-Anweisung zu erstellen, das gefälschte Objekt.Zur gleichen Zeit, können Sie ganz einfach konfigurieren Sie das Objekt, um Rückkehr Sie die gewünschten Werte für diese Eigenschaften, die Angelegenheit zu Ihrer test.Auch, die meisten dieser frameworks Unterstützung faking rekursiv, so dass sich die komplexen Objekte, die sich in Ihrer Art erhalten auch gefälscht, und so auf.

Es gibt Gründe, warum man vielleicht nicht wollen, verwenden Sie einen separaten Rahmen, in dem Fall denke ich, Reed Copsey Vorschlag wäre der manuelle Weg, es zu tun.

Wenn es keine Gründe, um zu vermeiden, hinzufügen von ein mocking framework (das wäre nur eine Abhängigkeit zu Ihrem test-Projekte, vorausgesetzt, Sie haben den split testing out), würde ich wärmstens empfehlen es für die komplexe Typen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top