10

次の行にifステートメントを書きました

if (value == value1 || value == value2 || value == value3 || value == value4)
    //do something

そして、常に 'value ==' の部分を繰り返さなければならないことに悩まされています。私の意見では、これは読みにくくする以外の目的には役立っていません。

上記のシナリオをより読みやすくする次の ExtensionMethod を作成しました。

public static bool IsEqualToAny<T>(this T value, params T[] objects)
{
    return objects.Contains(value);
}

今、私は簡単に書くことができます

if (value.IsEqualToAny(value1, value2, value3, value4))
    //do something

これは ExtensionMethod の適切な使用法ですか?

編集:

すべてのすばらしい答えをありがとう。記録のために:私は方法を保持しました。単純に使用できるという提案new []{value1,value2,value3,value4}.Contains(value)は正しいですが、私はこの種の if ステートメントを左から右に読むことを好みます (これらの値にこの値が含まれている場合ではなく、この値がこれらのいずれかと等しい場合)。各オブジェクトのインテリセンスにもう 1 つのメソッドが表示されることは、私にとっては問題ではありません。

4

8 に答える 8

5

無制限の拡張メソッドを作成することは珍しいことですT。特に、このアプローチでは、インテリセンスがすぐに使いにくくなります。

有効ではありますが、拡張メソッドとしてこれを回避する可能性があります。おそらく、標準の静的ユーティリティメソッドを使用するだけです。

C#3配列初期化構文はもっと簡単かもしれませんか?

bool isTrue = new[] { 1, 2, 3 }.Contains(3);

もちろん、大量のデータセットの場合は、HashSet<T>どこかにキャッシュすることをお勧めします;-p

于 2009-02-11T09:22:44.877 に答える
4

特定のアプリケーションまたはコンテキストにのみ役立つ機能を追加していません。拡張機能には明確な名前が付けられており、実装を見なくても動作は明らかです。

答えは「はい、そうです」です

于 2009-02-11T09:22:43.020 に答える
1

この拡張メソッドを使用する可能性のあるすべてのオブジェクトに、 Contains を適用して、Contains を適用することを保証するつもりですか?

特定のオブジェクトが operator== をオーバーロードして等価性をテストする場合、一般的なソリューションは失敗します。これにより、複数の == テストと真に同等ではなくなります。これは、拡張メソッドを記述することの危険性を示す良い例でもあります!

次の Linq コードは、演算子のオーバーロードを実装する場合と、オブジェクト参照を比較するデフォルトの == の意味を使用している場合に機能します。これは、V がオブジェクトとして与えられた場合、value が実際には value1、2、3、または 4 と同じオブジェクトであることを示します。この特定のケースでの値のタイプ:

V[] lv = { value, value2, value3, value4 };
if (lv.Any( v => v==value))
   // do something

または簡略版:

if (new List<V>{value, value2, value3, value4 }.Any( v => v==value))
   // do something

上記のラムダ式を汎用拡張メソッドで動作させることができませんでした。

私が素敵で読みやすい構文であると私が考えるものの良い例として(無関係であれば)、Pythonのイディオムは次のようになります

if value in (value1, value2, value3, value4):
于 2009-02-11T10:21:15.673 に答える
1

少し型にはまらないように見えますが、私にはよさそうです。

于 2009-02-11T09:16:55.157 に答える
1

かなり公平に思えますが、私は一歩後退します。この比較にビジネス上の意味を込めることはできますか? それらの値は何ですか?IsSpecialCustomerLocationおそらく、呼び出されたメソッドまたはコードの実際の意図を表現する何かを使用したほうがよいでしょう。

于 2009-02-11T09:17:03.597 に答える
1

そのタスクに LINQ メソッド構文を使用することもできます (System.Linq 名前空間を使用)。

            object[] objects = new object[10];
        objects.Contains(new MyClass());

うーん、ちょっと考えさせてください...ああ、あなたはすでにそれを使用しています。ただし、直接呼び出すのではなく、別のメソッドに入れました。

于 2009-02-11T09:19:35.790 に答える
1

そのために静的クラスを作成します。私はその解決策が好きではありません。すべてのクラスにメソッドを追加するのは少しやり過ぎに思えるからです。ただし、オブジェクト自体に機能を実行するように要求するため、OOD とはある程度一致します (ちょっと)。

それでも、アンチパターンがどのように形成されるかがわかるので、代わりに再利用可能なクラスを使用します。私はまだそれをアンチパターンと呼んでいませんが、これらの構造があまりにも多くポップアップする場合、すべてのオブジェクトが拡張メソッドで散らかってしまうため、読みやすさのアンチパターンと呼んでいます。名前空間の汚染のように見えますが、クラスメンバーの汚染です。

if (ConditionHelper.IsEqualToAny(value, value1, value2, value3)) 
{
    // Do something
}

同じ仕事をし、何も汚染しません。

于 2009-02-11T09:59:21.717 に答える