2014-01-07 57 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參數使用不同的名稱來避免。