9

私のアプリケーションは、属性enumを含むいくつかのを定義しています。[Flags]

これらのいずれかにフラグが設定されているかどうかを確認するための小さなユーティリティメソッドを作成したかったのでenum、次のことを思いつきました。

protected static bool IsFlagSet<T>(ref T value, ref T flags)
{
    return ((value & flags) == flags);
}

しかし、これにより、「演算子'&'はタイプ'T'および'T'のオペランドに適用できません」というエラーが発生します。

これを機能させることはできますか?

4

5 に答える 5

15

Enumクラスにはすでにユーティリティ関数があります: 、 MSDNEnum.HasFlag(Flag f)の例を参照してください

 if (petsInFamily.HasFlag(Pet.Dog))
        familiesWithDog++;

注:これはC#4で導入されました。また、非常に読みやすいものの、パフォーマンスの問題が発生する可能性があります。

于 2011-05-08T18:12:47.540 に答える
3

私の答えは遅すぎることを理解していますが、私はこの問題の本当に素晴らしい解決策を見つけました。.Net 4以降dynamic、C#で型を使用できるようになりました。メソッドは書き直すことができます:

protected static bool IsFlagSet<T>(T value, T flags)
{
    dynamic a = value;
    dynamic b = flags;
    return ((a & b) == flags);
}

その背後にある考え方dynamicにより、メソッド/演算子がタイプでサポートされている場合、実行を延期することができますT。したがって、&が定義されている場合T、ランタイムは成功です。

于 2013-08-19T12:14:24.083 に答える
2

エラーの理由は、ジェネリック型を「T、Tに対して演算子Xを定義する」として制限できないためです。その結果、C#はT、Tに定義された演算子Xがないと想定する必要があり、エラーを示します。

これは、==演算子に関連してよく議論される動作です-つまり、演算子==をC#のジェネリック型に適用することはできませんか?、ただし、すべての演算子に適用されます。

考えられる制約の完全なリストについては、http://msdn.microsoft.com/en-us/library/d5x73970(v = VS.100).aspxを参照てください。列挙型には制約がないことに注意してください(これは、具体的にはシナリオ)、演算子Xが定義されているタイプの場合も同様です。

于 2011-05-08T18:25:51.940 に答える
2

&はクラス型の演算子です。つまり、クラスTには、演算子&をオーバーロードするメソッドが必要です。

.Netは、すべてのクラスがそれを持っていることを期待することはできません。だから失敗します。

できることは、演算子のオーバーロードをメソッドとして宣言する基本クラスを作成することです。

次に、Constraintsを使用して、Tがその基本クラスを使用することを宣言します。

protected static bool IsFlagSet<T> where T: BaseclassWithAnd (ref T value, ref T flags)
{
    return ((value & flags) == flags);
}
于 2011-05-08T18:14:04.217 に答える
2

&操作を定義する型に型キャストする必要があります。

    protected static bool IsFlagSet<T>(ref T value, ref T flags)
    {
        return ((Convert.ToInt32(value) & Convert.ToInt32(flags)) == Convert.ToInt32(flags));
    }
于 2011-05-08T18:16:27.693 に答える