回到目錄 我們知道在Linq里的分組groupby可以對集合中一個或者多個欄位進行分組,並對其中一個屬性進行聚合,而Linq為我們提供了多種聚合方法,由aver,sum,count等,而在大叔許可權體系中,以上幾種聚合是不夠的,因為我們需要對許可權欄位進行按位聚合,或者說對它進行按位的或運算,這對於學過 ...
我們知道在Linq里的分組groupby可以對集合中一個或者多個欄位進行分組,並對其中一個屬性進行聚合,而Linq為我們提供了多種聚合方法,由aver,sum,count等,而在大叔許可權體系中,以上幾種聚合是不夠的,因為我們需要對許可權欄位進行按位聚合,或者說對它進行按位的或運算,這對於學過電腦基礎的同學不是什麼難事,按位求或,就是將數值先轉為二進位,進行兩個運算數進行求或,原則是:有1則1,全0才0,這是上學時老師教的,呵呵。
對於Linq的擴展方法微軟開發人員都放在了System.Linq這個命名空間下麵,所以咱們自己寫擴展時,也最好遵循這個原則,都寫在這個命名空間下,這樣在使用時也很方便,因為VS建立項目後,在config里會自己引用這個命名空間,在開發效率上是很高高的。
微軟為我們封裝的一些集合的擴展方法
namespace System.Linq { // 摘要: // 提供一組用於查詢實現 System.Collections.Generic.IEnumerable<T> 的對象的 static(在 Visual // Basic 中為 Shared)方法。 public static class Enumerable { public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func); public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func); public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector); public static bool Any<TSource>(this IEnumerable<TSource> source); public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
大叔照著葫蘆去畫飄
/// <summary> /// 按或進行位運算 /// 作者:倉儲大叔 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="source"></param> /// <param name="selector"></param> /// <returns></returns> public static int BinaryOr<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector) { int result = 0; foreach (var item in source) { result |= selector(item); } return result; }
在實現中使用時,與sum方法是一樣的,只不過sum是對數值進行求和,而BinaryOr是對數值按位求或,這兩者在運算結果上是完全不同的,如下所示
都是1,2,4,4,2,1進行求聚合
Sum()的結果:14
BinaryOr()的結果:7
對於按位運算的實際意義:它在Flags標識的枚舉上經常使用(枚舉元素值為2的N次冪),像在大叔框架里的許可權部分,也是使用了這種枚舉進行存儲的。