Frage

Ich habe eine Klasse, die eine Reihe von Eigenschaften enthält, etwa:

public class Update
{
    public int Quantity { get; set; }
    public decimal Price { get; set; }
    public string Name { get; set; }
}

Jede Instanz von Update Es müssen nicht unbedingt alle Eigenschaften festgelegt sein, und ein anderer Teil des Systems muss wissen, welche Eigenschaften festgelegt wurden und welche nicht.

Eine Option, die ich habe, besteht darin, alle Werttypen zu erstellen Nullable und so ein null Der Wert würde das Konzept darstellen, nicht festgelegt zu sein.Obwohl dies funktionieren würde, gefällt mir die Idee, einige Eigenschaften explizit zu haben, nicht wirklich Nullable (die Werttypen) und einige, die aufgrund der Tatsache, dass es sich um einen Referenztyp handelt, nullbar sind.Die Klassendefinition würde hässlich aussehen und ich bin nicht davon überzeugt, dass eine Nullprüfung semantisch der beste Ansatz ist.

Ich könnte eine Klasse erstellen, die sehr ähnlich ist Nullable<T> das hat keine Einschränkung für die T mit einem IsSet Eigentum.Ich bevorzuge diese Option gegenüber der Verwendung Nullable, aber ich würde trotzdem gerne sehen, ob jemand eine alternative Darstellung hat, die besser ist als die von mir vorgeschlagenen Optionen.

War es hilfreich?

Lösung

Sie sollten sich hier wirklich an die bereits bestehende Redewendung halten.Verwenden Sie die integrierte Nullfähigkeit.

Ich verstehe, dass Sie Bedenken haben, dass die NULL-Zulässigkeit für Wert- und Referenztypen unterschiedlich ist.Ihre Problemumgehung würde funktionieren.Aber es ist nur eine kosmetische Veränderung, die Ihnen wenig bringt.Ich empfehle in diesem Fall, dass Sie sich selbst ändern, anstatt den Code zu ändern.Versuchen Sie, sich an die bestehenden Konventionen anzupassen.

Bearbeiten:Manchmal müssen Sie in generischem Code einen Wert optional machen können.In diesem Fall müssen Sie einen benutzerdefinierten Optionstyp verwenden.Aus Erfahrung kann ich sagen, dass die Anwendung ziemlich unangenehm ist.Es ist nicht meine bevorzugte Lösung.

Andere Tipps

Die Referenztypen sind bereits nullbar, effektiv - wenn Sie verwenden int?, decimal? Und string dann kann jede Ihrer Eigenschaften null sein.

Das Problem tritt auf, wenn Sie das jemals einstellen möchten string value zu einem Nullverweis – wenn null tatsächlich ein gültiger Wert ist, der Ist Satz.

Du sicherlich könnte Schreib ein Maybe<T> Typ, aber ich bin mir nicht sicher, ob ich das tun würde – ich würde wahrscheinlich Benutze einfach null...Abgesehen von allem anderen wird es für andere, die den Code lesen und mit C#-Redewendungen vertraut sind, vertrauter sein.Trotz all der „Anti-Null“-Stimmung (die ich Tun Teilen in vielen Situationen) Es gibt Fälle, in denen dies der einfachste Ansatz ist.

Ich mag die Idee, einige Eigenschaften nicht zu haben (die Werttypen), und einige nicht (die Referenztypen) nicht zu haben (die Referenztypen)

Referenztypen sind offensichtlich nullfähig.

string t = null; //is totally valid

Ich würde sagen, dass Nullable genau das ist, was Sie für diesen Zweck verwenden möchten.Sie könnten die Mitglieder mit Eigenschaften umschließen (wie Sie es bereits tun), damit die Klasse normale Werte nach außen anzeigt, zusammen mit „Ist es gesetzt“-Methoden, um bei Bedarf zu überprüfen.Aber im Inneren würde ich Nullable verwenden.

Um Ihnen etwas Neues vorzuschlagen...Wenn Sie nur über eine Klasse wie Update mit einer begrenzten Anzahl von Mitgliedern sprechen, würde ich nur IsSet verwenden.

Aber wenn Sie z.B.Für eine Reihe ähnlicher Klassen mit diesem Verhalten oder vielen Eigenschaften könnte ich Ihnen die Verwendung von T4-Vorlagen empfehlen.Sie können beispielsweise Klasseneigenschaften (des benötigten Typs oder Attributs) wie beschrieben abrufen In diesem Artikel und automatisch Code basierend auf der Liste der Eigenschaften generieren (automatisches Implementieren jedes gewünschten Designs)

Ich könnte es genauer beschreiben, wenn es jemanden interessiert ...

Die Lösung hier zu

  • Verwenden Sie nullable überall dort, wo null keine gültige Option ist
  • Verwenden Sie einen Standardwert, wenn null eine gültige Option ist, Sie aber absolut sicher sind, dass ein bestimmter Wert nicht auftritt
  • Verwenden Sie für jede Eigenschaft ein boolesches Flag, wobei null ein gültiger Wert ist und Sie keinen Standardwert benennen können, der niemals verwendet wird.

Beispiele:Die Menge sollte nullwertfähig sein, denn wenn sie festgelegt ist, wird ihr Wert nie null sein

Der Name sollte standardmäßig auf „“ stehen, wenn der Name möglicherweise null ist (das Fehlen eines Namens) und Sie sicher sind, dass der Name niemals „“ sein wird.

Ein Flag, sagen wir nameSet, sollte verwendet werden, wenn Name möglicherweise einen Nullwert hat und Ihnen kein Standardwert einfällt.Dieses Flag wäre standardmäßig auf „false“ gesetzt und wenn Sie den Wert von „Name“ zum ersten Mal festlegen, sollte das Flag ebenfalls auf „true“ gesetzt sein.

Wenn Sie alle Ihre Eigenschaften auf die gleiche Weise behandeln möchten, besteht eine Lösung darin, eine Klasse zu erstellen, die ein Objekt und ein boolesches Flag enthält.Das Objekt würde den Wert der Eigenschaft speichern und das Flag würde speichern, ob die Eigenschaft initialisiert wurde, aber das gefällt mir nicht, weil es ein boolesches Flag erstellt, auch wenn es nicht benötigt wird.

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