5

В C# я могу выразить это:F # и явное преобразование в LINQ к XML

var xe = XElement.Parse("<foo></foo>"); 
var maybe = (bool?)xe.Element("bar"); 

Как это может быть выражено в F #?

Изменить: Я нашел эту вспомогательную функцию

let inline conv (x : ^a) : ^b = ((^a or ^b) : (static member op_Explicit : ^a -> ^b) (x)) 
+2

Смотрите здесь варианты: http://www.trelford.com/blog/post/F-XML-Comparison - (XElement-vs-XmlDocument-vs-XmlReaderXmlWriter-vs-Discriminated-Unions) .aspx – mydogisbox

ответ

5

К сожалению, XLinq сильно зависит от неявных и явных преобразований, что делает вещи немного сложнее.

Вы можете сделать процедуру для преобразования из XElement в опции BOOL:

let elementToBool e = 
    match e with 
    | null -> None 
    | e -> Some(XElement.op_Explicit e : bool) 

С этим, вы можете написать:

let xe = XElement.Parse("<foo><baz>true</baz></foo>") 
let bar = xe.Element (XName.op_Implicit "bar") |> elementToBool 
let baz = xe.Element (XName.op_Implicit "baz") |> elementToBool 

В F # Interactive, это будет конвертировать:

val bar : bool option = None 
val baz : bool option = Some true 

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

Использование функций преобразователя становится немного чище. Я приспособил код выше, чтобы использовать (немного модифицированные версии) ваш конвертер помощник рутинный:

let inline convi (x : ^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x) 
let inline conve (x : ^a) : ^b = ((^a or ^b) : (static member op_Explicit : ^a -> ^b) x) 

let xe = XElement.Parse("<foo><baz>true</baz></foo>") 
let elementToBool e = 
    match e with 
    | null -> None 
    | e -> Some(conve e : bool) 

let baz = "baz" |> convi |> xe.Element |> elementToBool 
let bar = "bar" |> convi |> xe.Element |> elementToBool 
+0

Спасибо за ответ. Я отмечу это как ответ. Я думаю, что использование (conve foo: Nullable )? = True - это немного более удобный синтаксис использования, хотя, хотя и не такой чистый, как синтаксис C#, но другая вспомогательная функция может это исправить. Помощник? = (Если я правильно помню) в System.Linq.Nullable namespaces (или около него). –

+1

Вы можете использовать 'XName.Get' вместо' XName.op_Implicit'. – luksan

+0

@luksan Хорошая точка - я всегда забываю об этом (обычно используют XLinq только с C#) –