代码之家  ›  专栏  ›  技术社区  ›  em70

操作员?“

  •  15
  • em70  · 技术社区  · 15 年前

    我刚刚看了 this page 当一个新的?提到接线员,我不清楚它的用法是什么。
    有人能提供一个快速的解释,张贴一个截图的代码,说明如何使用这个操作符,并可能提到一个用例吗?
    编辑 :这真的很尴尬,我注意到了吗?Don的发行说明中不再提到操作员。你知道为什么吗?

    3 回复  |  直到 9 年前
        1
  •  31
  •   Brian    15 年前

    在这个版本中有两个新的“特殊”操作符,(?)和(?)&…它们没有定义,但是可以用于重载,因此您可以自己定义它们。特殊的位是它们如何处理第二个操作数:它们要求它是有效的F标识符,但将其传递给函数,将运算符实现为字符串。换言之:

    a?b
    

    减至:

    (?) a "b"
    

    还有:

    a?b <- c
    

    减至:

     (?<-) a "b" c
    

    这些运算符的一个非常简单的定义可以是:

    let inline (?) (obj: 'a) (propName: string) : 'b =
        let propInfo = typeof<'a>.GetProperty(propName)
        propInfo.GetValue(obj, null) :?> 'b
    
    let inline (?<-) (obj: 'a) (propName: string) (value: 'b) =
        let propInfo = typeof<'a>.GetProperty(propName)
        propInfo.SetValue(obj, value, null)
    

    注意,由于gettor的返回类型是泛型的,所以在大多数情况下,您必须在使用站点指定它,即:

    let name = foo?Name : string
    

    尽管你仍然可以连锁反应(?)(从(?)的第一个参数开始)也是通用的):

    let len = foo?Name?Length : int
    

    另一个更有趣的实现是重新使用VB提供的callbyname方法:

    open Microsoft.VisualBasic    
    
    let inline (?) (obj: 'a) (propName: string) : 'b =
        Interaction.CallByName(obj, propName, CallType.Get, null) :?> 'b //'
    
    let inline (?<-) (obj: 'a) (propName: string) (value: 'b) =
        Interaction.CallByName(obj, propName, CallType.Set, [| (value :> obj) |])
        |> ignore
    

    这样做的好处是,它可以正确处理属性和字段,使用IDispatch COM对象等。

        2
  •  4
  •   Daniel Pratt    15 年前

    听起来像“?”运算符与动态语言运行时(DLR)相关。也就是说,当您希望在运行时而不是在编译时绑定到对象成员(方法、属性)时,可以使用它。

    这很有趣,因为我希望这也是动态成员调用在C中的工作方式。唉,C通过“伪”类型(“动态”IIRC)公开了这个功能。在我看来,这使得代码不那么清晰(因为您必须跟踪变量声明以了解调用是早绑定还是晚绑定)。

    我不知道确切的语法,但是如果我不得不猜测的话,它要么替换要么增加“.”(dot)操作符。如:

    let x = foo?Bar()
    

    或者:

    let x = foo.?Bar()
    
        3
  •  1
  •   jbtule    9 年前

    有一个模块 FSharp.Interop.Dynamic 在使用DLR实现动态运算符的nuget上。

    let ex1 = ExpandoObject() in
    ex1?Test<-"Hi";
    ex1?Test |> should equal "Hi";
    

    它是开源的,Apache许可证,您可以查看 implementation 包括单元测试 example cases .