根据键名选择枚举值

Loc*_*rde 6 c# linq enums

我有一个这样的枚举:

public enum Animals 
{ 
    CatOne = 12, 
    CatTwo = 13, 
    CatThree = 14, 
    DogOne = 21, 
    DogTwo = 22 
};
Run Code Online (Sandbox Code Playgroud)

大.

现在我想得到所有猫的价值..我想要做的是:

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();
}
Run Code Online (Sandbox Code Playgroud)

哪个工作正常.除了它看起来很难看.为什么我不能做类似的事情

Animals
    .Select(r => (int)r)
    .Where(r => r.StartsWith("Cat"))
    .ToArray();
Run Code Online (Sandbox Code Playgroud)

我知道这不起作用.那么是否有更好的方法来获取以某些字符串开头的枚举的所有值.

我知道我可以使用正则表达式来避免误报,但是,我现在保持简单.

谢谢.

Jon*_*eet 14

那么最简单的方法就是使用ToString以下命令获取名称:

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

或者使用Cast<>以避免演员Animals[]:

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

(我喜欢Cast<>OfType<>这里,我们真的希望每一个值是Animals-如果有什么不,一个例外是完全恰当的!)

然而,这一切对我来说都有点蠢 - 对枚举值的名称的任何重要性总是让人觉得有点毛茸茸,而且解析名称的特定位更是如此.您可能希望尝试使用属性装饰每个值以指定"组".

我还建议调用枚举Animal而不是Animals- 只有基于标志的枚举通常应该是复数,并且"一组Animals值"听起来非常奇怪.

(另外,您可能希望查看我的Unconstrained Melody项目,该项目允许对枚举进行类型安全,高效的通用访问,通过IL中合法但不能用C#表示的通用约束...)

  • @Bobson:我现在已经包含了一个使用`Cast`的版本 - 以及我对'OfType`的'Cast`的推理. (2认同)

Bob*_*son 13

这是一组妥协的代码 - 它不像你想要的那样干净,但它比foreach循环版本要好得多.

Enum.GetValues(typeof(Animals)).OfType<Animals>()
    .Where(x => x.ToString().StartsWith("Cat"))
    .Select(x => (int)x).ToArray();
Run Code Online (Sandbox Code Playgroud)