2014-01-07 49 views
1

考虑下面的记录定义和相应的方法:使用可选参数调用记录部件使用命名参数

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) 

试图使用命名的参数,无论是具有必需或可选参数,但不会编译。对于根据MSDN文档(http://msdn.microsoft.com/en-us/library/dd233213.aspx

命名参数只允许为方法,而不是让结合的功能,函数值,或lambda表达式示例

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

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

回答

4

根据你的样本,我会说你必须写MyRecord.Create(a=1, b=2)。或者是你的问题有一个错字?

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"来禁用,或者通过为create参数使用不同的名称来避免。