Wie implementiere ich richtig eine Eigenschaft in F #?
-
24-09-2019 - |
Frage
Betrachten Sie meinen ersten Versuch, eine einfache Art in F # wie folgt aus:
type Test() =
inherit BaseImplementingNotifyPropertyChangedViaOnPropertyChanged()
let mutable prop: string = null
member this.Prop
with public get() = prop
and public set value =
match value with
| _ when value = prop -> ()
| _ ->
let prop = value
this.OnPropertyChanged("Prop")
ich das jetzt teste über C # (dieses Objekt zu einem C # -Projekt ausgesetzt wird, so offensichtlich, C # Semantik wünschenswert ist):
[TestMethod]
public void TaskMaster_Test()
{
var target = new FTest();
string propName = null;
target.PropertyChanged += (s, a) => propName = a.PropertyName;
target.Prop = "newString";
Assert.AreEqual("Prop", propName);
Assert.AreEqual("newString", target.Prop);
return;
}
propName
richtig zugeordnet, meine F # Setter läuft, aber die zweite Assertion fehlschlägt, weil der zugrunde liegende Wert von prop
nicht geändert wird. Diese Art von Sinn macht mich, denn wenn ich mutable
vom prop
Feld entfernen, wird kein Fehler erzeugt (und man sollte sein, weil ich versuche, den Wert zu mutieren). Ich glaube, ich muss ein grundlegendes Konzept fehlen.
Was ist der richtige Weg / mutiert prop
in der Test
Klasse erneut zu binden, so dass ich meinen Unit-Test passieren kann?
Lösung
Versuchen Sie diese:
type Test() =
inherit BaseImplementingNotifyPropertyChangedViaOnPropertyChanged()
let mutable prop: string = null
member this.Prop
with public get() = prop
and public set value =
match value with
| _ when value = prop -> ()
| _ ->
prop <- value
this.OnPropertyChanged("Prop")
Sie müssen die Bindung wandelbar machen und dann seinen Wert in Ihrem Setter verändern. In Ihrem ersten Code, kreierten Sie gerade eine neue Bindung in Ihrem Setter (auch prop
genannt), so dass keine Veränderung sichtbar war.
Andere Tipps
Als Randbemerkung, würde ich wahrscheinlich if .. then
anstelle des match
Konstrukt, wie es der Code prägnanter macht (patterh Anpassung ist besonders wertvoll, wenn Sie den Wert agains mehrere komplexe Muster testen müssen). Auch public
ist der Standardzugang für member
, so dass Sie den Code ein bisschen machen prägnanter:
type Test() =
inherit BaseImplementingNotifyPropertyChangedViaOnPropertyChanged()
let mutable prop : string = null
member this.Prop
with get() = prop
and set(value) =
if value <> prop then
prop <- value
this.OnPropertyChanged("Prop")
In Ihrem Muster Spiel Sie verbindlich sind tatsächlich einen neuen Wert mit
let prop = value
Wenn Sie bindet ein Wert wie dies mit dem gleichen Namen, wird es den anderen Wert für den Umfang der neu einen Schatten erklärt. Ich glaube, was Sie wirklich tun möchte, ist dies:
prop <- value