Подтвердить что ты не робот

Утверждение аргумента в конструкторе структуры F #

Вот тривиальная структура С#, которая выполняет некоторую проверку на аргументе ctor:

public struct Foo
{
    public string Name { get; private set; }

    public Foo(string name)
        : this()
    {
        Contract.Requires<ArgumentException>(name.StartsWith("A"));
        Name = name;
    }
}

Мне удалось перевести это в класс F #:

type Foo(name : string) = 
    do 
        Contract.Requires<ArgumentException> (name.StartsWith "A")
    member x.Name = name

Однако я не могу перевести это в структуру в F #:

[<Struct>]
type Foo = 
    val Name : string
    new(name : string) = { do Contract.Requires<ArgumentException> (name.StartsWith "A"); Name = name }

Это дает ошибки компиляции:

Недопустимое выражение записи, последовательности или вычисления. Выражения последовательности должны быть форма 'seq {...}'

Это не допустимое выражение для построения объекта. Явные конструкторы объектов должны либо вызвать альтернативный конструктор, либо инициализировать все поля объекта и указать вызов конструктора суперкласса.

Я посмотрел this и this, но они не охватывают проверку аргумента.

Где я делаю неправильно?

4b9b3361

Ответ 1

Вы можете использовать блок then после инициализации структур. Он описывается для классов в вашей первой в разделе" Выполнение побочных эффектов в конструкторах", но он также работает и для структур.

[<Struct>]
type Foo = 
    val Name : string
    new(name : string) = { Name = name } 
                         then if name.StartsWith("A") then failwith "Haiz"

UPDATE:

Еще один способ ближе к вашему примеру - использовать ; (последовательный состав) и круглые скобки для объединения выражений:

[<Struct>]
type Foo = 
    val Name : string
    new(name : string) = 
        { Name = ((if name.StartsWith("A") then failwith "Haiz"); name) } 

Ответ 2

Если вы хотите избежать явных полей (val) и then, двух относительно эзотерических функций, вы можете использовать статический метод Create и придерживаться более распространенного синтаксиса определения типа:

[<Struct>]
type Foo private (name: string) = 
  member x.Name = name
  static member Create(name: string) =
    Contract.Requires<ArgumentException> (name.StartsWith "A")
    Foo(name)