使用命名参数调用具有可选参数的记录成员

时间:2014-01-07 18:31:51

标签: f# named-parameters

考虑以下记录定义和附带方法:

    type MyRecord = {
    FieldA : int
    FieldB : int
    FieldC : int option
    FieldD : int option
    } with
        static member Create(a,b,?c,?d) = {
            FieldA = a
            FieldB = b
            FieldC = c
            FieldD = d
            }

调用Create方法如下:

    //ok
    let r1 = MyRecord.Create(1, 2)
    //ok
    let r2 = MyRecord.Create(1,2,3)

尝试使用带有必需参数或可选参数的命名参数但不会编译。例如

    //Compilation fails with a message indicating Create requires four arguments
    let r2 = MyRecord.Create(FieldA = 1, FieldB =2)

根据MSDN文档(http://msdn.microsoft.com/en-us/library/dd233213.aspx

  

仅允许方法使用命名参数,而不允许使用自由绑定函数,函数值或lambda表达式。

因此,基于此,我应该能够使用命名参数来执行Create。我的语法有问题,还是我错误地解释了规则?有没有办法在这个上下文中使用命名参数?

2 个答案:

答案 0 :(得分:4)

根据您的样本,我会说您必须写MyRecord.Create(a=1, b=2)。或者这是你问题中的拼写错误?

答案 1 :(得分:1)

这适用于VS 2013:

使用:

type MyRecord = 
    {
        FieldA : int
        FieldB : int
        FieldC : int option
        FieldD : int option
    }
    with
        static member Create(a,b,?c : int,?d : int) = 
            { FieldA = a; FieldB = b; FieldC = c; FieldD = d }

允许你写:

let v = MyRecord.Create(a = 1, b = 2)

为了获得您想要的语法,您需要使用:

type MyRecord = 
    {
        FieldA : int
        FieldB : int
        FieldC : int option
        FieldD : int option
    }
    with
        static member Create(FieldA, FieldB, ?FieldC, ?FieldD) = 
            { FieldA = FieldA; FieldB = FieldB; FieldC = FieldC; FieldD = FieldD }

但是,这会导致您可能希望避免的一些编译器警告。这可以在您的记录声明之前通过#nowarn "49"禁用,或者通过为创建参数使用不同的名称来避免。