给定一个MyEnum和一个MyClass
[Flags]
enum MyEnum
{
first = 1,
second = 2,
third = 4,
forth = 8
}
class MyClass
{
public MyEnum MyEnum;
public uint Value;
}
还有一些价值观
var mcs = new[] {
new MyClass { MyEnum = MyEnum.first | MyEnum.third, Value = 10 },
new MyClass { MyEnum = MyEnum.second, Value = 20 },
new MyClass { MyEnum = MyEnum.first, Value = 100 },
};
此 LINQ 表达式将为枚举的每个值返回值的总和。
var ret = from p in Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
select new { MyEnum = p, Sum = mcs.Where(q => q.MyEnum.HasFlag(p)).Sum(q => q.Value) };
请注意,即使对于MyEnum.fourthvalue ,它也会返回一个“行” 0。
该表达式以枚举 ( Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()) 的值开始,然后对于每个值,它将mcs具有相同MyEnum( mcs.Where(q => q.MyEnum.HasFlag(p)).Sum(q => q.Value))的值相加
如果要排除未使用的枚举值:
var ret = from p in Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
let temp = mcs.Where(q => q.MyEnum.HasFlag(p)).Select(q => q.Value).ToArray()
where temp.Length > 0
select new { MyEnum = p, Sum = temp.Sum(q => q) };
该表达式以枚举 ( Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()) 的值开始,然后对于每个值,它“保存”mcs中具有相同MyEnum( let temp = mcs.Where(q => q.MyEnum.HasFlag(p)).Select(q => q.Value).ToArray()) 的值temp,跳过temp空的 ( where temp.Length > 0) 并对剩余的temp( select new { MyEnum = p, Sum = temp.Sum(q => q) }) 求和。请注意,如果您使用 an uint,则必须使用temp.Sum(q => q),但使用 anint您可以使用temp.Sum()(或者您可以使用temp.Sum(q => q))。
另一种方法是通过一个 doublefrom和一个group by
var ret = from p in Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
from q in mcs
where q.MyEnum.HasFlag(p)
group q.Value by p into r
select new { MyEnum = r.Key, Sum = r.Sum(p => p) };
它可能相当于使用SelectManyChaseMedallion 建议的使用(from编译器将 double 转换为 a SelectMany)