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而不是Animals- 只有基于标志的枚举通常应该是复数,并且“Animals值的集合”听起来很奇怪。

(另外,你可能想看看我的Unconstrained Melody项目,它允许通过在 IL 中合法但不能在 C# 中表达的泛型约束对枚举进行类型安全、高效的泛型访问...)

于 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 回答