F#-更改后设置属性
我有一个类,它的属性有几个副作用,在调用其setter时会激发这些副作用,例如激发的更改事件和/或呈现操作。如何设计一个只在属性值需要更改时才设置属性的函数 有了裁判,我会这样做:F#-更改后设置属性,f#,f#-3.0,F#,F# 3.0,我有一个类,它的属性有几个副作用,在调用其setter时会激发这些副作用,例如激发的更改事件和/或呈现操作。如何设计一个只在属性值需要更改时才设置属性的函数 有了裁判,我会这样做: let setIfChanged (oldVal: Ref<'T>) (newVal: 'T) = if newVal <> !oldVal then oldVal := newVal let y = ref 0 setIfChanged y 1 让setIfChanged(oldVal:
let setIfChanged (oldVal: Ref<'T>) (newVal: 'T) = if newVal <> !oldVal then oldVal := newVal
let y = ref 0
setIfChanged y 1
让setIfChanged(oldVal:Ref您可以执行以下操作:
let setIfChanged (oldVal: 'a byref) (newVal : 'a) = if newVal <> oldVal then oldVal <- newVal
let mutable test = 42
setIfChanged &test 24
你可以调用someObj?TheProperty我认为没有任何简单的好方法可以“免费”完成这项工作
有一个技巧可能会使这更容易一些,那就是实际上可以将属性的getter和setter视为函数,这样就可以将setIfChanged
编写为一个包含两个函数的函数:
let setIfChanged getter setter v =
if getter() <> v then setter(v)
编译器允许您访问get\p
和set\p
这一事实是一个鲜为人知的技巧,因此对许多人来说可能有点困惑。
为了完整起见,下面是我用于测试的A
的定义:
type A() =
let mutable p = 0
member x.P
with get() = p
and set(v) = printfn "Setting!"; p <- v
type A()=
设可变p=0
x.P.成员
使用get()=p
和set(v)=printfn“Setting!”;p这如何处理对象属性?例如setIfChanged foo.Text“bar”
。此外,我无法控制在外部C#库中定义的类及其成员。@dannytoone啊,这必须对字段起作用。它不能对属性起作用……我不知道您无权访问这些类型。@dannytoone为您提供了另一种选择,使用F#中的动态支持来“包装”Access,允许你在这个过程中进行操作。这是一个耻辱(通常你会希望设置者在没有任何改变的情况下聪明地不做副作用)你不能改变来源——我个人会考虑包装攻击类型-托马斯回答似乎是一个很好的方法来做这个短小的事情。
let setIfChanged getter setter v =
if getter() <> v then setter(v)
let a = A()
setIfChanged a.get_P a.set_P 0
setIfChanged a.get_P a.set_P 1
type A() =
let mutable p = 0
member x.P
with get() = p
and set(v) = printfn "Setting!"; p <- v