كيف يمكنني تنفيذ خاصية بشكل صحيح في F#؟
-
24-09-2019 - |
سؤال
النظر في محاولتي الأولى ، نوع بسيط في f# مثل ما يلي:
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")
الآن أختبر هذا عبر C# (يتعرض هذا الكائن لمشروع C# ، لذا فإن دلالات C# واضحة أمر مرغوب فيه):
[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
تم تعيينه بشكل صحيح ، يتم تشغيل جهاز F# الخاص بي ، لكن التأكيد الثاني يفشل لأن القيمة الأساسية لـ prop
لم يتغير. هذا النوع من المنطقي بالنسبة لي ، لأنه إذا أزلت mutable
من prop
الحقل ، لا يتم إنشاء أي خطأ (ويجب أن يكون المرء لأنني أحاول تحوير القيمة). أعتقد أنني يجب أن أفتقد مفهومًا أساسيًا.
ما هي الطريقة الصحيحة لإعادة التوصيل/التحور prop
في ال Test
الفصل حتى أتمكن من اجتياز اختبار الوحدة الخاص بي؟
المحلول
جرب هذا:
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")
تحتاج إلى جعل الربط قابل للتغيير ثم تغيير قيمته في Setter الخاص بك. في الكود الأولي الخاص بك ، كنت فقط إنشاء ملزمة جديدة (تسمى أيضًا prop
) داخل Setter الخاص بك ، لذلك لم يكن هناك تغيير مرئي.
نصائح أخرى
كملاحظة جانبية ، ربما أستخدمها if .. then
بدلا من ال match
بناء لأنه يجعل الكود أكثر إيجازا (مطابقة Patterh ذات قيمة خاصة عندما تحتاج إلى اختبار القيمة مرة أخرى أنماط متعددة معقدة). ايضا، public
هو الوصول الافتراضي ل member
, ، حتى تتمكن من جعل الكود أكثر إيجازًا:
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")
في تطابق النمط الخاص بك ، تقوم بالفعل بربط قيمة جديدة
let prop = value
عندما تقوم بربط قيمة كهذه بنفس الاسم ، فإنها ستظل القيمة الأخرى لنطاق الفئة المعلنة حديثًا. أعتقد أن ما تريد فعله بالفعل هو:
prop <- value