给定一个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.fourth
value ,它也会返回一个“行” 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) };
它可能相当于使用SelectMany
ChaseMedallion 建议的使用(from
编译器将 double 转换为 a SelectMany
)