Класс F # с необычной конструкцией - PullRequest
0 голосов
/ 27 июня 2018

У меня есть тип класса, определенный следующим образом:

type T1(?maybei1: int, ?maybei2: int) =

Все следующие работы:

let t11 = T1(1, 2)
let t12 = T1(1)
let t13 = T1()

но этот не (как ожидалось):

let tuple = (1, 2)
let t14 = T1 tuple //error: expected int but given int * int

с другой стороны, если я определю свой тип как:

type T2(i1: int, i2: int) =

тогда я могу создать экземпляр с помощью кортежа

let tuple = (1, 2)
let t24 = T2 tuple //ok

но я теряю опции:

let t22 = T2(1) //error
let t23 = T2() //error

Я пробовал с дополнительным конструктором:

type T3(?maybei1: int, ?maybei2: int) =
    new (i1: int, i2: int) = T3(i1, i2)

type T4(i1: int, i2: int) =
    new (?maybei1: int, ?maybei2: int) =

но я не смог получить версию, которую я мог бы создать как с необязательными параметрами, так и с кортежем. Любая идея (без делегирования, инкапсуляции или наследования, только один тип)?

EDIT

Томас Петричек нашел способ заставить его работать; достаточно хорошо.

Однако, как он также упоминает, есть еще кое-что, что, imho, звучит не совсем правильно. Например, без конструктора перегрузки, который принимает кортеж, мы в конечном итоге окажемся в ситуации, когда:

let tup = (1, 2)

let t1 = T (1, 2) //ok
let t2 = T tup //error

В первом случае компилятор отображает два параметра в типы опций, как и ожидалось конструктором, я ожидаю, что то же самое происходит во втором случае. Кто-нибудь знает, есть ли причина, почему это не так?

1 Ответ

0 голосов
/ 27 июня 2018

Если вы добавите перегруженный конструктор, который принимает явный кортеж в качестве единственного аргумента, тогда все способы создания экземпляра работают:

type T(?maybei1: int, ?maybei2: int) =
    new (tup:int*int) = T(fst tup, snd tup)
    member x.Values = maybei1, maybei2

T(1)
T(1, 2)
T(maybei2=2)
let tup = (1, 2)
T tup

Честно говоря, я не совсем уверен, каковы правила передачи кортежей в качестве аргументов для методов с несколькими параметрами - это несколько сложно. Логично, что вы можете думать о членах как о кортеже, но это не вся история из-за необязательных параметров и компиляции (она компилируется как обычный метод), поэтому поведение несколько тонкое. Но определение явной перегрузки с использованием кортежа (который будет скомпилирован как принятие System.Tuple) делает свое дело!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...