using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; namespace Chronos.Reflection.Internal { public static class Extensions { /// /// Finds the intersection of a group of groups. /// public static IEnumerable IntersectAll(this IEnumerable> groups) { HashSet hashSet = null; foreach (IEnumerable group in groups) { if (hashSet == null) { hashSet = new HashSet(group); } else { hashSet.IntersectWith(group); } } return hashSet == null ? Enumerable.Empty() : hashSet.AsEnumerable(); } /// /// Determines if an enum has the given flag defined bitwise. /// Fallback equivalent to .NET's Enum.HasFlag(). /// public static bool HasFlag(this Enum value, Enum flag) { long lValue = Convert.ToInt64(value); long lFlag = Convert.ToInt64(flag); return (lValue & lFlag) != 0; } #if !NETFX_CORE private static MethodInfo[] extensionMethodsCache; /// /// Searches all assemblies for extension methods for a given type. /// public static IEnumerable GetExtensionMethods(this Type type) { // http://stackoverflow.com/a/299526 if (extensionMethodsCache == null) { extensionMethodsCache = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(assembly => assembly.GetTypes()) .Where(potentialType => potentialType.IsSealed && !potentialType.IsGenericType && !potentialType.IsNested) .SelectMany(extensionType => extensionType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) .Where(method => method.IsExtension()) .ToArray(); } return extensionMethodsCache.Where(method => method.GetParameters()[0].ParameterType.IsAssignableFrom(type)); } #endif public static bool IsExtension(this MethodInfo methodInfo) { return methodInfo.IsDefined(typeof(ExtensionAttribute), false); } } }