Отсутствие инициализатора коллекции раздражает некоторые XAML-ориентированные API, такие как Workflow 4.0, которые полагаются на инициализаторы коллекции вместо ctors, например,
new Sequence { Activities = { WriteLine { Text = "In the sequence!" } } };
В таких случаях императив .Add () неудобенпотому что значение концептуально декларативно, хотя оно технически изменчиво / обязательно.Тем не менее, не существует общего базового класса для набора всех действий, которые объявляют дочерний объект Activity: элемент «Activities» является pattern , а не интерфейсом, поэтому вы не можете просто написать обычную вспомогательную функцию, котораядобавляет детей к любой деятельности.К счастью, на помощь приходят ограничения члена F #.
Чтобы написать это:
Sequence() |> add [Sequence(DisplayName="InnerSeq"); WriteLine(Text = InArgument<_>("In the sequence!"))]
Сначала вам нужно определить встроенную вспомогательную функцию под названием "add":
let inline add (children: Activity seq) =
let inline doAdd (activity: ^Activity) : ^Activity when ^Activity : (member get_Activities : unit -> Activity Collection) =
let collection = (^Activity : (member get_Activities : unit -> Activity Collection) (activity))
for child in children do
collection.Add(child)
activity
doAdd
Это все еще не так хорошо, как синтаксис C #, но, по крайней мере, оно все еще декларативно.ИМХО, это не столько ошибка F #, сколько API-интерфейсы, ориентированные на коллекцию, но, по крайней мере, F # позволяет обойти это.