4

我阅读了以下文章

http://studentguru.gr/b/kron/archive/2012/09/26/c-template-metaprogramming-and-f-type-providers.aspx

它显示了一种使用 F# 类型提供程序进行编译时斐波那契序列生成的方法。解决方案在文章中,但最终程序是

> cat .\fib.fs
type fib = Playground.StaticFibonacci<100000>
printfn "Fibonacci(100000) has %d digits" fib.Value.Length
> fsc .\fib.fs -o fib.exe -r:.\FibonacciTypeProvider.dll –nologo
> .\fib.exe
Fibonacci(100000) has 20899 digits

这看起来很强大。我想知道是否可以为 INPC ( INotifyPropertyChanged ) 创建一个类型提供程序,这样您就可以代替

open System.ComponentModel

type MyObject() =
    let mutable propval = 0.0

    let propertyChanged = Event<_, _>()
    interface INotifyPropertyChanged with
        [<clievent>]
        member x.PropertyChanged = propertyChanged.Publish

    member this.MyProperty
        with get() = propval
        and  set(v) =
            propval <- v
            propertyChanged.Trigger(this, new PropertyChangedEventArgs("MyProperty"))

你也许可以写

open System.ComponentModel

type MyObject() =
    let mutable propval = 0.0

    let propertyChanged = Event<_, _>()
    interface INotifyPropertyChanged with
        [<clievent>]
        member x.PropertyChanged = propertyChanged.Publish

    member this.MyProperty : INPCTypeProvider<double>

因此,在我浪费半天时间深入研究这个问题之前,也许更知情的人会告诉我我在浪费时间,而且这种级别的元编程是不可能的。

4

1 回答 1

6

I do not think you can achieve this with F# type providers (but I can see that that it would be nice). There is a number of problems and thoughts I can think of:

  • In your example, your INPCTypeProvider<double> would have to return something like a representation of a "property". This is not possible, because properties are not first-class values (unlike events). If they were, you wouldn't need a type provider...

  • Type provider cannot be parameterized by an existing type, so you cannot write say:

    type MyNotifyObject = ProvideNotifiable<MyObject>
    

    If this was possible, ProvideNotifiable could be a provider taking a type and building a new type with additional interface implementation. But this is not possible at the moment.

  • If you only need simple types, you might be able to create something like:

    type MyObject = ProvideNotifiable<"MyProperty:int, OtherProperty:string">
    

    This could generate a type with the two properties (defined in the string), but you cannot add anything more to the generated type (although, you might be able to generate actual type using generative provider and inherit from it...) I think this is probably the best you can do.

Aside from type providers, you can simplify the implementation of INotifyPropertyChanged a bit by using quotations. This F# snippet gives a simple example that makes the implementation safer.

于 2012-12-09T13:41:54.173 回答