1

公式の初心者向けガイドを使用して、Reactive Extensions for .NETを試してみましたが、メソッドのオーバーロードの多くが機能していませんでした(System.Reactiveを参照しました)。ガイドの方法が古くなっているのか、それとも他の理由があるのか​​はわかりません(アセンブリが不足している場合は、plsが教えてくれます)。元のコードと変更されたコードは次のとおりです。

using System;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Windows.Forms;

namespace RxFormsSandbox
{
    class Program
    {
        static void Main(string[] arguments)
        {
            var textBox = new TextBox();
            var form = new Form { Controls = { textBox } };

            // MY CODE (WORKING)

            var mouseMoves = Observable.FromEvent<MouseEventHandler, MouseEventArgs>(
                handlerAction => (_, args) => handlerAction(args),
                handler => form.MouseMove += handler,
                handler => form.MouseMove -= handler);

            var input = Observable.FromEvent<EventHandler, EventArgs>(
                handlerAction => (_, args) => handlerAction(args),
                handler => textBox.TextChanged += handler,
                handler => textBox.TextChanged -= handler);

            var mouseMovesSubscription = mouseMoves.Select(x => x.Location.ToString()).Subscribe(Console.WriteLine);
            var inputSubscription = input.Subscribe(x => Console.WriteLine(textBox.Text)); // can I do this without directly accessing 'label' (via sender)
            // END OF MY CODE

            // ORIGINAL CODE AS PROVIDED IN THE SAMPLE

//            var mouseMoves = Observable.FromEvent<MouseEventArgs>(form, "MouseMove");
//            var input = Observable.FromEvent<MouseEventArgs>(textBox, "TextChanged");
//
//            var mouseMovesSubscription = mouseMoves.Select(x => x.EventArgs.Location.ToString()).Subscribe(Console.WriteLine);
//            var inputSubscription = input.Subscribe(x => Console.WriteLine(((TextBox)x.Sender).Text));
            // END OF ORIGINAL SAMPLE CODE


            using (new CompositeDisposable(mouseMovesSubscription, inputSubscription))
            {
                Application.Run(form);
            }
        }
    }
}

メソッドのシグネチャがリリース間で実際に変更されていることを前提として、私のソリューションについて私を悩ませていることがいくつかあります。より良い方法があるかどうかを尋ねたいと思います。

  1. 私の書き直したバージョンはかなり長く、表現力が低いと思います。(理想的にはマジックストリングを導入せずに)短くする方法はありますか?
  2. input.Subscribe(x => Console.WriteLine(textBox.Text)); 外部コードを参照しているため、あまり良くありません。'sender'プロパティを介して何らかの方法でアクセスしたいと思います。

私のアセンブリはNuGetからのもので、そのバージョンは1.0.10621.0です。

4

1 に答える 1

3

古い方法を模倣したい場合は、次のFromEventPattern方法を使用できます。

var mouseMoves = Observable.FromEventPattern<MouseEventArgs>(form, "MouseMove"); 

この方法で行うことの唯一の欠点は、FromEventメソッドを使用するときに得られる型の安全性が失われることです。(FromEventPatternデリゲートを使用するオーバーロードもありますが、EventHandler<T>これMouseMoveは.Net 2.0より前のものです)

2つ目のポイントとして、「外部コードの参照」が悪いのはなぜですか。クロージャはC#言語の大部分を占めており、クロージャを回避する理由は実際にはありません。実際、イベントサブスクリプションコードのコードでは、それも実行しています(フォームのキャプチャ)。

var mouseMoves = Observable.FromEvent<MouseEventHandler, MouseEventArgs>(
               handlerAction => (_, args) => handlerAction(args),
               handler => form.MouseMove += handler,
               handler => form.MouseMove -= handler);
于 2012-07-06T17:48:43.143 に答える