C # Eigenschaften - Frage festlegen

8

Ich arbeite in C # und fange an, mit Eigenschaften zu spielen. Eine Sache, die ich nicht weiß, ist, was ist der beste Weg, wo die Logik für die Set-Accessoren von Klasseneigenschaften und wie man mit den Fehlern umgehen.

Sagen wir zum Beispiel, dass ich diese (Basis-) Klasse habe:

%Vor%

Sagen Sie jetzt, ich habe eine Anforderung für die Age-Eigenschaft, 0 & lt; Alter & lt; 100. Wo lege ich die Logik dazu?

Sollte ich es in der Eigenschaft setzen?

%Vor%

oder durch die Klasse, die ein Person-Objekt erstellt?

%Vor%

Was passiert nun, wenn ein Problem mit NewAge auftritt (es erfüllt meine Einschränkung nicht)? Sollte ich eine benutzerdefinierte Ausnahme erstellen und diese werfen? Sollte ich nur eine Nachricht drucken, die besagt, dass ein gültiges Alter anzugeben ist?

Ich habe etwas gegoogelt und ich kann nichts finden, was meine Fragen vollständig beantwortet. Ich brauche ein Buch: - /

    
Ryan Rodemoyer 27.05.2009, 14:47
quelle

10 Antworten

23

Verwenden Sie den Eigenschaften-Setter, der aus diesem Grund vorhanden ist (Hinzufügen von Funktionen zu einem Feld).

Wenn der Wert außerhalb des Bereichs überschritten wird, können Sie ArgumentOutOfRangeException oder einfach auslösen setze es auf den minimalen (oder maximalen) Wert, aber das hängt von deiner Prozessanforderung ab.

    
Adrian Godong 27.05.2009, 14:49
quelle
11

Ich würde es so implementieren:

%Vor%

Ein paar Dinge zu beachten:

  • Ändern Sie nicht ihren Wert, anstatt eine Ausnahme auszulösen. Dies ist ein unerwartetes Verhalten.
  • Das .NET-Framework löst in Settors Argument * -Ausnahmen aus, daher würde ich sagen, dass es eine gute Idee ist, dieser Praxis zu folgen. In diesem Fall ist ArgumentOutOfRangeException perfekt, IMO.
  • Wenn Sie auf das Argument in Ausnahmebedingungsnachrichten und XML-Dokumenten verweisen, lautet der Standard, das Argument "value" zu verwenden, nicht den Namen Ihrer Eigenschaft.
  • Ich würde MinAge und MaxAge als private Würmer in Ihrer Klasse empfehlen, fallen Sie nicht in die Falle, Fehlermeldungen mit Bereichsgrenzen in ihnen zu codieren. Es gibt nichts Schlimmeres als "5 in ungültig, bitte geben Sie eine Zahl dazwischen ein 1 und 10 ", wenn jemand später die Spezifikation ändert, aber vergisst, eine Zeichenfolge zu aktualisieren.
Matthew Brindley 27.05.2009 15:02
quelle
6

Sie möchten die Logik in den Setter setzen und eine Ausnahme auslösen, wenn sie die Anforderung nicht erfüllt. Sie sollten jedoch auch eine statische IsValidAge-Methode oder etwas erstellen, damit Klassen, die eine Person erstellen, den Alterswert überprüfen können, anstatt nur zu sehen, ob eine Ausnahme ausgelöst wird. Alternativ könnten Sie MinAge und MaxAge-Eigenschaften haben, so dass der aufrufende Code überprüfen könnte, ob das Alter, das sie gerade setzen, zwischen ihm liegt.

Erstellen Sie jedoch keinen benutzerdefinierten Ausnahmetyp, verwenden Sie ArgumentOutOfRangeException oder etwas ähnliches.

    
Max Schmeling 27.05.2009 14:50
quelle
3

Legen Sie es in die Eigenschaft. Das ist einer der Hauptzwecke von Eigenschaften!

Bedenken Sie, dass Sie die Verantwortung auf die niedrigst mögliche Ebene legen werden. Das von Ihnen angegebene Beispiel erfordert nichts anderes als den Parameter value , um eine Entscheidung zu treffen. Es hängt nicht einmal von anderen Mitgliedern derselben Klasse ab. Es gibt keinen Grund für den Rest der Klasse zu wissen, wie die Gültigkeit für die Age-Eigenschaft funktioniert, und sicherlich keinen Grund dafür, dass ein anderer Code sie kennt.

    
John Saunders 27.05.2009 14:50
quelle
3

Vielleicht möchten Sie sich die IDataErrorInfo-Schnittstelle ansehen.

Wenn Sie diese Schnittstelle in Ihrer Klasse implementieren, öffnen Sie die Klasse für andere Mechanismen, die von den zusätzlichen Fehlerinformationen profitieren können.

    
SergioL 27.05.2009 14:55
quelle
1

Ich werde den Advokaten des Teufels spielen und eine Antwort geben, warum Sie es NICHT in den Setzer setzen wollen. Es gibt viele Fälle, wenn Sie in der Lage sein möchten, den Wert Ihrer Age-Eigenschaft festzulegen, und zu einem späteren Zeitpunkt fragen, ob dieses Objekt in einem holistischen Sinne gültig ist.

Halten Sie zum Beispiel Ihre Immobilie einfach:

%Vor%

Wenn dann ein ungültiger Wert übergeben wird, können Sie eine IsValid-Funktion haben, die anzeigt, ob das Objekt in Ordnung ist. Dies kann sehr nützlich sein, da Sie neben einer einfachen Altersbeschränkung auch eine kompliziertere Validierung durchführen können.

%Vor%

Für etwas Einfaches wie dieses gibt es nicht viel Vorteil, aber bedenken Sie auch, dass Sie dies in Ihrer Persistenzschicht verwenden können, damit Sie sicherstellen können, dass jedes Objekt, das NICHT gültig ist, niemals persistiert wird. In diesen Fällen möchten Sie nicht unbedingt eine Ausnahme auslösen.

Bedenken Sie auch Folgendes:

%Vor%

Das ist nur Pseudocode, aber Sie verstehen, was ich meine. Dies ist etwas, was Sie nicht innerhalb eines Setter tun können, oder zumindest nicht auf eine Weise, die wartbar ist.

    
Joseph 27.05.2009 15:01
quelle
0

Verwenden Sie den Setter und verwenden Sie ArgumentOutOfRangeException, wie andere bereits gesagt haben.

Manchmal werden Sie eine andere Methode aufrufen, normalerweise OnAgeChanged (int age), wo Sie die Validierung durchführen können (was ein Aufruf einer anderen Methode sein kann, damit Sie sie überall verwenden können) und einen Event-Handler aufrufen angeschlossen, möglicherweise andere Logik anwenden, abhängig davon, wie Sie Ihr Objekt verwenden. Das ist in Ihrem Szenario möglicherweise nicht erforderlich, aber für Eigenschaften ist das ziemlich üblich. Vor allem, wenn Sie ein Formular aktualisieren möchten - das Formular würde sich in das AgeChanged-Ereignis einklinken, um sich selbst zu aktualisieren.

    
Richard Hein 27.05.2009 14:58
quelle
0

Wenn Sie faktorisiertes Design machen (dh es ist wichtig, dass der Zustand des Objekts zu allen Zeitpunkten während der Lebensdauer des Objekts gültig ist), dann sollten Sie dies im Konstruktor einstellen und überprüfen. In einem Komponentendesign sollten Sie dies in der Methode überprüfen, die die Eigenschaft verwendet, z. B.

%Vor%

Static void main ist ein Client-Code und kein guter Ort für Geschäftslogik.

    
MatthewMartin 27.05.2009 15:05
quelle
0

Danke für die Antworten! Falls du hier mal neugierig warst, was ich an meinem kleinen Beispiel (obwohl es jetzt genauer geht) ändere (basierend auf den Kommentaren).

%Vor%     
Ryan Rodemoyer 27.05.2009 15:18
quelle
0

Ihre aktualisierte Antwort ist gut, aber Sie sollten ein kleines Stück in Ihrem Setter / Validierung

bereinigen %Vor%     
ebrown 27.05.2009 17:43
quelle

Tags und Links