15

イベントIObservableから作成する C# コードを複製しようとしています。Button.Clickこのコードを F# に移植したいと考えています。

エラーなしでコンパイルされる元の C# コードを次に示します。

Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
                                    h => new RoutedEventHandler(h),
                                    h => btn.Click += h,
                                    h => btn.Click -= h))

F# で同じことをしようとして失敗したのは次のとおりです。

Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
            Func<EventHandler<RoutedEventArgs>, RoutedEventHandler>(fun h -> RoutedEventHandler(h)),
            Action<RoutedEventHandler>(fun h -> btn.Click.AddHandler h),
            Action<RoutedEventHandler>(fun h -> btn.Click.RemoveHandler h))

ステートメントの 2 行目を除いて、すべてが満足しています。

F# コンパイラは、コンストラクターへのパラメーターとしてfun h -> RoutedEventHandler(h)を除きたくないため、不平を言います。hRoutedEventHandler

一方、C# コンパイラは問題なく受け入れられるようです。h => new RoutedEventHandler(h)

興味深いことに、両方のコード サンプル (C# と F#) で、 の型hEventHandler<RoutedEventArgs>.

F# コンパイラから得られるエラー メッセージは次のとおりです。

エラー 2 この式はタイプ obj -> RoutedEventArgs -> unit を持つことが期待されていましたが、ここではタイプ EventHandler を持っています

RoutedEventHandlerPresentationCore 内で見つけた署名は次のとおりです。

public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);

ご覧のとおり、パラメーターとしてobjectandを使用するため、F# コンパイラーは実際には正しいものです。RoutedEventArgs

C# コンパイラが舞台裏で行う魔法で、F# コンパイラでは機能しないものがありますか、それともここで何かが欠けているだけですか?

いずれにせよ、どうすればこれを F# で機能させることができますか?

4

2 に答える 2

17

IObservable<_>WPF Button.Clickイベントを作成するために私が知っている最も簡単な方法は、それをキャストすることです。

open System
open System.Windows.Controls

let btn = new Button()
let obsClick = btn.Click :> IObservable<_>

obsClickを調べる...

val obsClick : IObservable<Windows.RoutedEventArgs>

これが可能なのは、標準の.NETイベントのF#表現がタイプ(この場合)であるためIEvent<Windows.RoutedEventHandler,Windows.RoutedEventArgs>です。ドキュメントからわかるように、IEventはIObservableを実装しています。つまり、F#では、すべてのイベントはすでにIObservable。です。

于 2011-02-27T06:25:29.807 に答える
6

Joel Mueller はスポットライトを当てているので、記録として: C# コードを直接翻訳すると、次のようになります。

Observable.FromEvent(
    (fun h -> RoutedEventHandler(fun sender e -> h.Invoke(sender, e))),
    (fun h -> b.Click.AddHandler h),
    (fun h -> b.Click.RemoveHandler h)
)
于 2011-02-27T14:31:31.823 に答える