Вызов элемента записи с дополнительными параметрами с использованием именованных аргументов

Рассмотрим следующее определение записи и сопутствующий метод:

    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)

Именованные аргументы разрешены только для методов, но не для связанных функций, значений функций или лямбда-выражений.

Итак, исходя из этого, я смогу использовать именованные аргументы для выполнения Create. Что-то не так с моим синтаксисом или я неправильно интерпретирую правила? Есть ли способ использовать именованные аргументы в этом контексте?


person genericdeveloper    schedule 07.01.2014    source источник


Ответы (2)


Основываясь на вашем примере, я бы сказал, что вам нужно написать MyRecord.Create(a=1, b=2). Или это опечатка в вашем вопросе?

person FremyCompany    schedule 07.01.2014

Это работает в 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" перед объявлением записи или избежать, используя другое имя для аргументов создания.

person Reed Copsey    schedule 07.01.2014