Ich weiß, dass es auf diese Frage bereits eine Unmenge von Antworten gibt, aber keine davon schien mir richtig zu sein. Mein Problem ist, dass ich keine Leistungseinbußen haben möchte und bereit bin, allein aus diesem Grund ein wenig Wortklauberei in Kauf zu nehmen. Ich auch nicht zu viel für automatische Eigenschaften entweder, die mich auf die folgende Lösung geführt:
public abstract class AbstractObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual bool SetValue<TKind>(ref TKind Source, TKind NewValue, params string[] Notify)
{
//Set value if the new value is different from the old
if (!Source.Equals(NewValue))
{
Source = NewValue;
//Notify all applicable properties
foreach (var i in Notify)
OnPropertyChanged(i);
return true;
}
return false;
}
public AbstractObject()
{
}
}
Mit anderen Worten: Die obige Lösung ist praktisch, wenn es Ihnen nichts ausmacht, dies zu tun:
public class SomeObject : AbstractObject
{
public string AnotherProperty
{
get
{
return someProperty ? "Car" : "Plane";
}
}
bool someProperty = false;
public bool SomeProperty
{
get
{
return someProperty;
}
set
{
SetValue(ref someProperty, value, "SomeProperty", "AnotherProperty");
}
}
public SomeObject() : base()
{
}
}
Profis
- Keine Reflexion
- Meldet nur, wenn alter Wert != neuer Wert
- Mehrere Objekte gleichzeitig benachrichtigen
Nachteile
- Keine automatischen Eigenschaften (Sie können jedoch Unterstützung für beides hinzufügen!)
- Etwas weitschweifig
- Boxen (kleiner Leistungseinbruch?)
Aber es ist immer noch besser, als das hier zu tun,
set
{
if (!someProperty.Equals(value))
{
someProperty = value;
OnPropertyChanged("SomeProperty");
OnPropertyChanged("AnotherProperty");
}
}
Für jede einzelne Eigenschaft, was durch die zusätzliche Ausführlichkeit zu einem Alptraum wird ;-(
Ich behaupte nicht, dass diese Lösung leistungsfähiger ist als die anderen, sondern nur, dass sie eine praktikable Lösung für diejenigen ist, denen die anderen vorgestellten Lösungen nicht zusagen.
0 Stimmen
Siehe stackoverflow.com/questions/1329138/ für eine compilergeprüfte Art der Implementierung von INotifyPropertyChanged. Vermeidung von Eigenschaftsnamen als magische Zeichenkette.
8 Stimmen
code.google.com/p/notifypropertyweaver kann von Nutzen sein
9 Stimmen
Obiger Link ist tot. github.com/SimonCropp/NotifyPropertyWeaver
1 Stimmen
Obwohl ich adäquate Alternativen hatte, war nichts für mein Team so schmerzlos wie die Postsharp-Lösung Domänen-Toolkit (wird mit normalem Postsharp in der kommenden v3.0 gebündelt werden, denke ich). [NotifyPropertyChanged] auf die Klasse, [NotifyPropertyChangedIgnore] auf die Requisiten zu ignorieren.
3 Stimmen
Sie könnten stattdessen DependencyObject und DependencyProperties verwenden. HA! Ich habe einen Witz gemacht.
0 Stimmen
@Codest und jetzt ist dein Link tot
7 Stimmen
@joao2fast4u github.com/Fody/PropertyChanged/wiki/
0 Stimmen
Ich stimme mit dem Auftraggeber überein. Es ist wirklich traurig, dass es das in Roslyn noch nicht gibt. Außerdem muss es eine Möglichkeit geben, zu vermerken, dass eine Eigenschaft vom Wert einer anderen abhängig ist (idealerweise mit Attributen und dem nameof-Operator).
6 Stimmen
Zu dieser Zeit war es nicht möglich, Änderungen an C# vorzunehmen, da wir ein riesiges Backlog mit Abhängigkeiten hatten. Damals, als MVVM geboren wurde, haben wir uns nicht sonderlich um die Lösung dieses Problems bemüht, und ich weiß, dass das Patterns & Practices-Team ein paar Versuche unternommen hat (daher haben Sie auch MEF als Teil dieses Forschungs-Threads erhalten). Heute denke ich, dass [CallerMemberName] die Antwort auf das obige Problem ist.
0 Stimmen
Ich glaube, @tom-gilder hat eine bessere Antwort. stackoverflow.com/a/18002490/4062881
0 Stimmen
ObservableCollection
eliminiert die Notwendigkeit der ImplementierungOnPropertyChanged
für einfache Situationen. Siehe So geht's: Erstellen und Binden an eine ObservableCollection y ObservableCollection .