Как я правильно реализую свойство в F#?

Рассмотрите мою первую попытку, простой тип в 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 правильно присвоен, мой Метод set F# работает, но вторые утверждают, перестал работать потому что базовое значение prop не изменяется. Этот вид имеет смысл мне, потому что, если я удаляю mutable от prop поле, никакая ошибка не сгенерирована (и нужно быть то, потому что я пытаюсь видоизменить значение). Я думаю, что должен пропускать фундаментальное понятие.

Что состоит в том, чтобы снова переплести/видоизменить корректный путь prop в Test класс так, чтобы я мог передать свой модульный тест?

6
задан Greg D 2 April 2010 в 14:56
поделиться

3 ответа

Попробуйте следующее:

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")

Вам нужно сделать привязку изменяемой, а затем изменить ее значение в сеттере. В исходном коде вы просто создавали новую привязку (также называемую prop ) в своем сеттере, поэтому никаких изменений не было видно.

8
ответ дан 8 December 2019 в 05:54
поделиться

В качестве примечания я, вероятно, использовал бы , если .. then вместо конструкции match, поскольку она делает код более лаконичным (сопоставление паттерха особенно ценно, когда вам нужно проверить значение на множестве сложных шаблонов). Кроме того, 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") 
9
ответ дан 8 December 2019 в 05:54
поделиться

В вашем совпадении шаблона вы фактически связываете новое значение с

let prop = value

Когда вы связываете подобное значение с тем же именем, оно затеняет другое значение для области видимости вновь объявленного. Я полагаю, что на самом деле вы хотите сделать следующее:

prop <- value
5
ответ дан 8 December 2019 в 05:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: