5

メソッドにオプションを渡すために列挙型または整数を書くのが好きです。(int 1,2,4,8、...)オプションがtrueまたはfalseかどうかを確認するためのパターンまたはメソッドがC#にありますか。二変数関数で簡単にできるはずだと思います。

class Program
{
    public enum Option
    {
        Option_A = 1,
        Option_B = 2,
        Option_C = 4,
        Option_D = 8,
    }

    static void Main(string[] args)
    {
        int activeOption = 5; // Means I activeted the Option_A and Option_C
        if (IsOption(activeOption, Option.Option_A)) { /*do work*/ }
        if (IsOption(activeOption, Option.Option_B)) { /*do work*/ }
        if (IsOption(activeOption, Option.Option_C)) { /*do work*/ }
        if (IsOption(activeOption, Option.Option_D)) { /*do work*/ }
    }

    private static bool IsOption(int activeOption, Option option)
    {
        /*Evaluate if IsOption is true or false*/
        throw new NotImplementedException();
    }
}

編集

このように作成できるオプションの数は制限されていますか?

4

5 に答える 5

10

列挙型にはフラグが含まれているため(または、必要に応じてビットフィールドです)、列挙型ににを追加する必要がありますFlagsAttribute

[Flags]
public enum Option
{
    Option_A = 1,
    Option_B = 2,
    Option_C = 4,
    Option_D = 8,
}

そして、チェックは通常、ビットごとの演算子を使用して行われます。int変数を使用しているため、キャストも必要になります。

if(((Option)activeOption & Option.Option_A) != Option.Option_A) //...

この厄介さをカプセル化したい場合は、Smudge202の回答にリンクされている記事を確認してください。.NET 4を実行している場合は、それを行う必要はありません。seheの回答を確認してください。

ただし、実際には型の変数をOption直接使用してみて、オプションをビット単位または演算子と組み合わせる必要があります。

Option activeOption = Option.Option_A | Option.Option_C;

もちろん、このスキームを使用すると、作成できるオプションの数が制限されます。int(列挙型のデフォルトの基になるタイプ)には32ビットしかないため、そのままにしておくと、32の異なるオプションしか作成できません。を使用するlong場合は、64の異なるオプションがあります。

[Flags]
public enum Option : long
{
    Option_A = 1,
    Option_B = 2,
    Option_C = 4,
    Option_D = 8,
    // blah blah
}

ただし、任意の数のオプションが必要な場合は、おそらく戦略を変更する時期です。列挙型のように動作するカスタム型を作成することもできますが、通常のフラグ以外の列挙型とHashSet<Option>

public enum Option
{
    Option_A = 1, // notice the sequential values now
    Option_B = 2,
    Option_C = 3,
    Option_D = 4,
}

HashSet<Option> options = new HashSet<Option> { Option.Option_A, Option.Option_C };
if(options.Contains(Option.Option_A)) // ...
于 2011-05-20T09:23:49.857 に答える
3

ビット単位のANDを使用して、のビットoptionがに設定されているかどうかを確認しactiveOptionます。また、演算子が機能するように、両方のパラメーターを同じタイプにする必要があります(とにかくビットマスクのビットチェックしています)。Option

private static bool IsOption(Option activeOption, Option option)
{
    return (activeOption & option) == option;
}
于 2011-05-20T09:23:31.510 に答える
2

上記のFlagsAttributeに加えて、C#にはEnum.HasFlagメソッドがあります

using System;

[Flags] public enum DinnerItems {
   None = 0,
   Entree = 1,
   Appetizer = 2,
   Side = 4,
   Dessert = 8,
   Beverage = 16, 
   BarBeverage = 32
}

public class Example
{
   public static void Main()
   {
      DinnerItems myOrder = DinnerItems.Appetizer | DinnerItems.Entree |
                            DinnerItems.Beverage | DinnerItems.Dessert;
      DinnerItems flagValue = DinnerItems.Entree | DinnerItems.Beverage;
      Console.WriteLine("{0} includes {1}: {2}", 
                        myOrder, flagValue, myOrder.HasFlag(flagValue));
   }
}
// The example displays the following output:
//    Entree, Appetizer, Dessert, Beverage includes Entree, Beverage: True
于 2011-05-20T09:48:39.423 に答える
1

フラグ属性を使用する列挙を見てください。

http://www.codeproject.com/Articles/37921/Enums-Flags-and-Csharp-Oh-my-bad-pun.aspx

于 2011-05-20T09:26:30.433 に答える
1

.NET 4.0を使用している場合は、を使用できますHasFlag

static void Main(string[] args)
{
    Option activeOption = (Option)5; // Means I activeted the Option_A and Option_C
    if (activeOption.HasFlag(Option.Option_A)) { /*do work*/ }
    if (activeOption.HasFlag(Option.Option_B)) { /*do work*/ }
    if (activeOption.HasFlag(Option.Option_C)) { /*do work*/ }
    if (activeOption.HasFlag(Option.Option_D)) { /*do work*/ }
}
于 2011-05-20T13:36:13.910 に答える