7

私は次のような列挙型を持っています:

public enum Animals 
{ 
    CatOne = 12, 
    CatTwo = 13, 
    CatThree = 14, 
    DogOne = 21, 
    DogTwo = 22 
};

偉大な。

今、私はすべての猫の値を取得したい..私がやろうとしていることはこれです:

public static int[] GetCatValues()
{

    List<int> catValues = new List<int>();

    foreach(var cat in Enum.GetNames(typeof(Animals)))
    {
        Animals animal;

        if(cat.StartsWith("Cat"))
        {
            Enum.TryParse(cat, out animal);
            catValues.Add((int)animal);
        }       
    }

    return catValues.ToArray();
}

これは問題なく動作します。それが醜いことを除いて。なぜ私は次のようなことができないのですか

Animals
    .Select(r => (int)r)
    .Where(r => r.StartsWith("Cat"))
    .ToArray();

私はそれがうまくいかないことを知っています。特定の文字列で始まる列挙型のすべての値を取得するより良い方法はありますか。

おそらく正規表現を使用して誤検出を回避できることはわかっていますが、今のところ単純にしています。

ありがとう。

4

4 に答える 4

15

妥協案のコード セットを次に示します。探しているものほどきれいではありませんが、foreach ループ バージョンよりははるかに優れています。

Enum.GetValues(typeof(Animals)).OfType<Animals>()
    .Where(x => x.ToString().StartsWith("Cat"))
    .Select(x => (int)x).ToArray();
于 2013-03-12T15:38:33.670 に答える
14

最も簡単なアプローチは、次を使用して名前を取得することですToString

return ((Animals[]) Enum.GetValues(typeof(Animals)))
    .Where(r => r.ToString().StartsWith("Cat"))
    .Select(r => (int) r) // Assuming you want this
    .ToArray();

または、Cast<>へのキャストを回避するために使用しAnimals[]ます:

return Enum.GetValues(typeof(Animals))
    .Cast<Animals>()
    .Where(r => r.ToString().StartsWith("Cat"))
    .Select(r => (int) r) // Assuming you want this
    .ToArray();

(私たちは本当にすべての値がそうであることを期待しているので、ここを好みます-Cast<>何かOfType<>がそうでない場合は、例外が完全に適切です!)Animals

ただし、これはすべて私には少し厄介な感じがします。列挙値の名前を重要視すると、常に少し厄介に感じ、名前の特定のビットをさらに解析します。「グループ」を指定する属性で各値を装飾してみてください。

また、フラグベースの列挙型のみが一般的に複数形である必要があり、「値のコレクション」は明らかに奇妙に聞こえるのAnimalではなく、列挙型を呼び出すことをお勧めします。AnimalsAnimals

(また、 ILでは合法であるがC#では表現できないジェネリック制約を介して、列挙型へのタイプセーフで効率的なジェネリックアクセスを可能にする私のUnconstrained Melodyプロジェクトを確認することをお勧めします...)

于 2013-03-12T15:34:06.447 に答える
2

これを行うより良い方法は、フラグを使用することです。

[Flags]
public enum Animals 
{ 
    CatOne = 1, 
    CatTwo = 2, 
    CatThree = 4, 
    DogOne = 8, 
    DogTwo = 16,
    AllCats = Animals.CatOne | Animals.CatTwo | Animals.CatThree,
    AllDogs = Animals.DogOne | Animals.DogTwo 
};

もちろん、これは列挙型の番号を付け直すことができる場合にのみ機能し、これらの値で何をする必要があるかを正確に知らなければ、それがあなたに合っているかどうかを言うのは難しい.

于 2013-03-12T15:38:42.477 に答える
1

やや醜いですが、あなたのケースに合うかもしれません:

この場合、猫は整数ではなく実際の列挙型になります。

var cats = Enum.GetNames(typeof(Animals))
    .Where (e => e.StartsWith("Cat"))
    .Select (e => Enum.Parse(typeof(Animals), e));
于 2013-03-12T15:38:02.943 に答える