2012-07-06 59 views
0

我已經開始使用官方的beginner's guide官網回顧.NET的Reactive Extensions,但很多方法重載對我來說都不起作用(我引用了System.Reactive)。我不確定這是否是因爲如何引導已過時或者有其他原因(如果我錯過了一些程序集,請告訴我)。這裏原來並改變了代碼:反應式擴展缺少方法重載

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));並不是很好,因爲它引用了外部代碼。我想以某種方式通過'發件人'屬性訪問它。

我的程序集來自NuGet,它的版本是1.0.10621.0。

回答

3

如果你想模仿舊的方式,你可以使用FromEventPattern方法:

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

做這種方式唯一的缺點是你失去了類型安全,您使用FromEvent方法時得到。 (FromEventPattern也有使用委託過載,但與EventHandler<T>交易,但MouseMove預.NET 2.0)

關於你的第二點,爲什麼「引用外碼」是一件壞事? Closures是C#語言的很大一部分,真的沒有理由避免它們。事實上,在事件申購代碼你的代碼你正在做的一樣好(捕捉的形式):

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

您可以使用'FromEventPattern'簡單的過載,像這樣:'VAR mouseMoves = Observable.FromEventPattern (handler => form.MouseMove + = handler,handler => form.MouseMove - = handler);'。 – Enigmativity 2012-07-06 23:40:40

+0

有關Rx和事件的更詳細指導,請參閱http://introtorx.com/Content/v1.0.10621.0/04_CreatingObservableSequences.html#FromEvent – 2012-07-26 09:41:27