2

(C# で) パラメーターをイベント ハンドラーに渡してから、イベント ハンドラーをデタッチできるようにする必要があります。

イベント ハンドラーをアタッチし、パラメーターを渡します。

_map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);

イベントは期待どおりに呼び出されます。イベント ハンドラーをデタッチしようとしています。

_map.MouseLeftButtonUp -= (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);

コードはエラーなしで実行されますが、デタッチされていないようです。

イベント ハンドラーを従来の方法で (パラメーターを渡さずに) アタッチすると、次のようになります。

_map.MouseLeftButtonUp+=_map_MouseLeftButtonUp;

そしてデタッチ

_map.MouseLeftButtonUp -= _map_MouseLeftButtonUp;

すべてが期待どおりに機能します

より従来の方法でイベント ハンドラー (パラメーターを受け取る) を切り離す

_map.MouseLeftButtonUp -= _map_MouseLeftButtonUp2;

デリゲートが一致しないというエラーが表示されます(これは理にかなっています)

したがって、私の質問は次のとおりです。パラメーターを渡すときにイベントハンドラーが実際に切り離されていないのはなぜですか?この問題を回避する方法はありますか?

4

2 に答える 2

1

その理由は、2 つのデリゲートが等しくないためです。

  // You add one delegate instance 
  _map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);

  // ..And try to remove another one (not previous!) That's why the first delegate remains unremoved
  _map.MouseLeftButtonUp += (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);

あなたは自分自身を納得させることができます

  var x = (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);
  var y = (sender, e) => _map_MouseLeftButtonUp2(sender, e, showResultsWindow);

  if (Object.Equals(x, y)) { // <- You expected this behaviour
    ...
  }
  else { // <- Alas, this is a real situation: x != y
    ...
  }

このような動作の理由は、Object.Equals がオーバーライドされていない場合 (デリゲートの場合はオーバーライドされていない場合)、Object.Equals は Object.RefrenceEquals と同じように機能し、インスタンスの参照 (アドレス) をチェックするためです。確かに、x と y のアドレスは異なり、2 つのデリゲートも異なります

于 2013-08-01T13:33:55.903 に答える