2009-01-30 5 views
7

Wenn ich meine XAML mit einigen Daten verbinde, benutze ich oft den "Get" -Teil einer Eigenschaft, um etwas Logik zu machen. Wie die Summe der Summen einer Liste geben oder prüfen, ob etwas positiv ist.Logik wird Teil der Eigenschaft. Gute Übung?

Zum Beispiel:

public List<SomeClass> ListOfSomeClass{get;set;} 

public double SumOfSomeClass 
{ 
    get 
    { 
    return ListOfSomeClass.Sum(s => s.Totals); 
    } 
} 

public bool SumPositive 
{ 
    get 
    { 
    if(SumOfSomeClass >= 0) 
     return true; 
    else 
     return false; 
    } 
} 

So kann ich zu SumPositive und SumOfSomeClass binden können. Wird dies als gute Praxis angesehen? Auch wenn es komplexer wird? Oder wäre es besser, eine Methode aufzurufen und das Ergebnis zurückzugeben? Was ist mit Anrufen zu einer anderen Klasse oder sogar einer Datenbank?

Antwort

14

Es wird erwartet, dass Eigenschaftengetter schnell und idempotent sind (d. H. Dort sollten keine destruktiven Aktionen ausgeführt werden). Obwohl es vollkommen in Ordnung ist, über eine in-memory Sammlung von Objekten zu iterieren, würde ich es nicht empfehlen, irgendeine Art von schwerem Heben in entweder oder Teilen durchzuführen. Und wenn ich von Iteration spreche, würde ich das Ergebnis zwischenspeichern, um einige Millisekunden zu sparen.

+1

"ein paar Millisekunden sparen" - Nanosekunden? –

+1

idempotent hat eine breitere Bedeutung als das - es bedeutet, dass Sie das gleiche Ergebnis erhalten, indem Sie die Operation wiederholt aufrufen, anstatt von einem gespeicherten Zustand betroffen zu sein. http://en.wikipedia.org/wiki/Idempotent –

1

Ich sage ja, aber versuchen Sie, auf einer privaten Variablen de Ergebnisse von ListOfSomeClass.Sum (s => s.Totals) zu speichern. Besonders, wenn Sie es mehr als einmal benutzen.

1

Eine komplexe Logik in Getter/Setter ist keine gute Praxis. Ich empfehle, komplexe Logik zu separaten Methoden (wie GetSumOfXYZ()) zu verschieben und memoization in Eigenschaftenaccessoren zu verwenden.

Sie können komplexe Eigenschaften vermeiden, indem Sie ObjectDataProvider verwenden - es ermöglicht Ihnen, eine Methode zum Abrufen von Daten zu definieren.

1

Ich sehe kein direktes Problem (außer die Liste ist ziemlich riesig), aber ich würde persönlich die myInstance.SomeList.Sum() Methode verwenden, wenn möglich (. NET> = 2.0).

1

Für grundlegende Berechnungen von Feldern oder anderen Eigenschaften in der Auflistung wäre es akzeptabel, dies innerhalb der Get-Eigenschaft zu tun. Wie alle anderen sagten, sollte wahre Logik niemals im Getter gemacht werden.

0

Hängt davon ab ... wenn dies auf einer Domain-Entität wäre, dann wäre ich nicht dafür, komplexe Logik in einem Getter zu haben und insbesondere nicht in einem Setter. Die Verwendung einer Methode (für mich) signalisiert einem Verbraucher der Entität, dass eine Operation ausgeführt wird, während ein Getter eine einfache Abfrage signalisiert.

Nun, wenn diese Logik in einem ViewModel war, dann denke ich, der Getter-Aspekt ist ein bisschen mehr verzeihlich/erwartet.

0

Ich denke, dass es ein gewisses Maß an Logik gibt, die in Getters und Setter erwartet wird, sonst haben Sie nur eine Art verschachtelte Möglichkeit, Ihre Mitglieder öffentlich zu machen.

2

Ja, es sei denn, es handelt sich um eine Operation, die möglicherweise Auswirkungen auf die Leistung hat. In diesem Fall sollten Sie eine Methode verwenden, anstatt (wie es intuitiver für den Endbenutzer ist, dass ein Verfahren langsam sein könnte, während eine Eigenschaft schnell sein wird)

1

Sie bitte, dass Getter dies ändern:

public bool SumPositive 
{ 
    get 
    { 
    return SumOfSomeClass >= 0; 
    } 
} 

Sie verwenden bereits einen booleschen Ausdruck, keine explizite Rückgabe von true oder false.

+0

Das, was ich tatsächlich in meinem Code verwende. Im Beispiel soll es "komplexer" aussehen;) – Sorskoot

1

Ich mag Ihre Namenskonventionen und stimme der Verwendung von Inhalten wie Ihrem Beispiel in Eigenschaften-Gettern zu, wenn Sie eine API zur Verwendung bereitstellen mit Bindung.

Ich stimme nicht mit dem Punkt überein, den andere über das Verschieben von Code in eine Methode gemacht haben, nur weil es rechenintensiv ist - das ist kein Unterschied, den ich je gemacht hätte langsamer als eine Eigenschaft.

Ich glaube, dass Eigenschaften auf dem Objekt, auf dem sie aufgerufen werden, side-effect-free sein sollen. Es ist viel schwieriger zu garantieren, dass sie keinen Einfluss auf die weitere Umgebung haben - selbst eine relativ triviale Eigenschaft könnte Daten in den Speicher ziehen oder zumindest den Prozessor-Cache oder den vm-Zustand ändern.

0

Ich würde vorsichtig sein, irgendeine Logik in den Getter einer Eigenschaft zu setzen. Je teurer es ist, desto gefährlicher ist es. Andere Entwickler erwarten, dass ein Getter sofort einen Wert zurückgibt, genau wie einen Wert aus einer Membervariablen. Ich habe viele Instanzen gesehen, in denen ein Entwickler eine Eigenschaft bei jeder Iteration einer Schleife verwendet und denkt, dass sie nur einen Wert zurückbekommen, während die Eigenschaft tatsächlich viel Arbeit macht. Dies kann zu einer erheblichen Verlangsamung der Codeausführung führen.