5

私はそのような拡張メソッドを作成しました..

public static bool AllFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
    bool allSet = true;
    int enumVal = input.ToInt32(null);

    foreach (T itm in values)
    {
        int val = itm.ToInt32(null);
        if (!((enumVal & val) == val)) 
        {
            allSet = false;
            break;
        }
    }

    return allSet;
}

これは必要な目的にはうまく機能しますが、これらの値のみが設定されているかどうかをチェックする同じ署名を持つメソッドを作成する必要があります。

基本的にはこのようなものです。

public static bool OnlyTheseFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
}

これを行う唯一の方法は、使用可能なすべての列挙値を取得して、設定されているものを確認し、提供された 2 つだけが使用されていることを確認することです。

ある種のビット演算を使用してこの問題を解決する別の方法はありますか?

4

5 に答える 5

5

必要なすべてのフラグで「or」を実行し、入力と比較します - 等しい必要があります。次のように、左側に値を計算するための正しいループがあります。

var onlyTheseFlagsSet = (value[0] | value[1]) == input;
于 2012-11-19T02:30:31.407 に答える
2

独占要件とは、

input = values[0] | values[1] | ... | values[values.Length - 1]

だから、ここにあなたの実装があります:

return input.ToInt32(null) == values.Aggregate(0, 
       (total, next) => total | next.ToInt32(null));
于 2012-11-19T02:39:17.390 に答える
1

これにより、各入力値のビットが反転します。それらのみが設定されている場合、結果の値はゼロになります。それ以外の場合、値が設定されていない場合はビットを 1 に反転し、input値をゼロ以外のままにします。

public static bool OnlyTheseFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
    int enumVal = input.ToInt32(null);

    foreach (T itm in values)
    {
        int val = itm.ToInt32(null);
        enumVal = enumVal ^ val;                
    }

    return (enumVal == 0);
}
于 2012-11-19T02:34:28.410 に答える
0

何か不足していますか、params T[] 値を合計して、入力が結果と等しいかどうかを確認できませんか?
これらのフラグだけが必要な場合は、入力はこれらのフラグの合計に等しくなければなりません。

于 2012-11-19T02:30:59.660 に答える
0

入力を列挙型に変換できると仮定します。

foreach(MyFlags flag in values)
    if (!input.HasFlag(flag))
        return false;

return true;

はい、私はそのように怠け者です。

于 2012-11-19T02:38:19.043 に答える