イベントの送信者は常に汎用オブジェクトである必要がありますか?


10

C#でイベントをプログラミングするとき、次の形式でデリゲートを作成することをお勧めします。

delegate XEventHandler(object sender, XEventArgs e);

私の質問は、デリゲートの最初の引数ですobject sender。常にジェネリックである必要がありobjectますか?タイプの送信者があると、object常に次のようなコードになります。

val = ((ConcreteType)sender).Property;

または、さらに詳細な、

ConcreteType obj = sender as ConcreteType
if (obj != null) { ... }

強く型付けされた送信者に対する1つの議論は、他のオブジェクトが型を気にすることなくイベントを転送できることです。これはGUI環境では理にかなっているかもしれませんが、GUI以外でもメリットがあるかどうかはわかりません。

送信者のクラスが常に(少なくとも抽象クラスとして)わかっている場合はどうなりますか?私は実装していますたとえば、ListChanged抽象的にイベントをListクラス、および他のクラスは、(例えば、それを継承しようとしている場合はLinkedListArrayList)、それはタイプの送信者と私のデリゲートを定義するために、すべての権利でありますかList

delegate ListChangedEventHander(List sender, ListChangedEventArgs e);

または、従来型object senderをより具体的なタイプに変更することの欠点はありますか?

回答:


10

この時点では、ほとんどが(かなり強力な)規則です。つまり、その規則に従わないライブラリを作成すると、奇妙なことになります。

イベントデザイン・ガイドラインは言います:

DOを使用するobjectイベントハンドラの最初のパラメータの型として、そしてそれを呼び出しますsender

ただし、現在のガイダンスでは、イベントに独自のカスタムデリゲートを定義するのではEventHandler<T>なく、可能であれば代わりに使用するように指示されていることに注意してください。

設計に関しては、イベントの元の設計者が元々予見していなかった状況でも、イベントハンドラーの再利用を促進すると思います。


2
うーん... Microsoftがガイドラインをすべての人に適用できるように十分に一般化することを決定したからといって、他のすべての人が彼らのガイドラインに従うことが良い考えだとは限りません。「他の誰も」が他の何百万人もの開発者が使用するコードを書いていない可能性が非常に高いです。私はあなたが提供したリンクからの推奨の約2/3に固執しました。
2014年

実を言うと、この「ガイドライン」は、Windows APIのハンガリー語表記のようなものです。素晴らしい人が本当に正当な理由でそれを始めて、それから他の誰もがそれを悪用し始めました。ガイドラインがある場合、そのガイドラインの背後には十分な理由があるはずです。そして、何私はこのガイドラインの理由はそれだと思うSystem.Windows.Forms名前空間は、イベントが最も頻繁に使用されている場所であり、それはに加入する意味を成していたClickのイベントButtonCheckBox。したがって、送信者一般的である必要があります。...
sampathsris 2014年

...しかし、他の、より具体的な、含まれている機能の領域に関しては、送信者はジェネリッククラスである必要はないかもしれません。Listsのクラス階層の例をもう一度参照してください。
sampathsris 2014年

11
@ダンク:それがポイントです。このガイドラインは、主に他のユーザーが使用するコードに関係するフレームワーク設計ガイドラインに基づいています。それが最善の解決策ではなく、最も驚くべきことではないからです。これはフレームワークにとって最良のオプションです。小規模なライブラリの場合、ユースケースが適切に指定されていれば、適用できるガイダンスは少なくなります。Microsoftは本の冒頭でそのように明言しています。
Magus 2014年

1
私はその答えについては議論していません。信頼できる情報源から来ているので、私はそれを支持しさえしました。私はガイドラインを使用しないと言っているだけです。イベントが特定のデータを送信することになっている場合は、特定のデータを送信します。また、イベント機能は、意図した使用方法で使用すれば問題なく機能します。
2014年

0

推奨の理由は、既存のコード、特にパブリックインターフェイスの変更を必ずしも必要としない将来の変更を可能にするためです。

イベントメカニズム自体は引き続き「VB6」スタイルのイベントに使用できますが、シグネチャを変更する必要がある場合は、既存のすべてのコンシューマーを変更する必要があります(さらに悪いことに、同じイベントの新しいバージョンを作成します)。推奨されるアプローチを使用すると、新しいアイテムが既存のアイテムを継承する限り、既存のコードを修正せずに署名を更新できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.