如何将F#类型提供程序生成的类型公开给C#和XAML

Fed*_*gui 4 c# xaml f# type-providers f#-data

所以,我正在使用XML Type Provider从XML文档创建类型.

XML文件中的一个元素具有以下Date属性:

<Edit Date="06/30/2015 16:57:46"
      ... />
Run Code Online (Sandbox Code Playgroud)

这当然导致类似这样的类型:

type Edit = 
    inherit XmlElement

    member Date:  DateTime
    ...
Run Code Online (Sandbox Code Playgroud)

有没有办法可以添加以下代码:

 member this.LocalTime
    with get() =
        this.Date.ToLocalTime()
Run Code Online (Sandbox Code Playgroud)

结果Edit类型?

这样做的原因是我绑定了EditXAML的实例,我真的不想写一个IValueConverter只是为了做到这一点.

编辑:

所以,我才意识到这些类型不适合我的XAML.相反,我得到的实例FSharp.Data.Runtime.BaseTypes.XmlElement当然甚至不包含我在F#代码中看到的属性.我还需要从C#代码中使用这些类型,甚至在那里我只得到XmlElement没有属性的s

我知道我可以在XAML中使用XPath来导航其中的XElements,但是我仍然需要一种以强类型方式访问结果对象模型的方法,包括C#和XAML.

EDIT2:

所以现在我写了一个这样的类型扩展:

type Catalog.Edit with
    member this.LocalTime with get() = this.Date.ToLocalTime()
Run Code Online (Sandbox Code Playgroud)

我看到F#代码中的成员就像生成的成员一样.然而,这种方法有两个缺点:

1 - 它迫使我把我namespace改成a module,这不太方便,因为这些类型都是从C#代码中消耗掉的,在那里我把它们看作模块类的嵌套类,这很难看.

2 - 我仍然无法从C#和XAML中看到这个成员(也不是生成的成员).

在描述的场景中实现这一点的正确方法是什么?

Tom*_*cek 6

XML和JSON的F#数据类型提供程序是擦除类型提供程序.这意味着从F#中使用它们时看到的类型实际上并不存在于运行时 - 它们被替换为一些底层运行时表示(此处XmlElement).

不幸的是,这意味着类型不是真正的类型,因此它们仅对F#可见.

我的建议是使用F#记录定义一个简单的域类型,并将XML中的数据加载到您的记录中.这是一项更多的工作,但它也为您提供了更多的安全性,因为您明确定义了结构 - 因此,如果您的XML发生更改,您将知道您还需要更改XAML代码!

它应该像这样简单:

type Edit = { Date : DateTime }

let GetData () = 
  let doc = MyXmlType.Load("somefile.xml")
  seq { for item in doc.Edits -> { Date = item.Date } }
Run Code Online (Sandbox Code Playgroud)