using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace Web.Core { public static class ExtensionMethods { public static Dictionary ToDictionary(this IEnumerable> kvps) { Dictionary res = new Dictionary(); foreach(KeyValuePair kvp in kvps) { res[kvp.Key] = kvp.Value; } return res; } public static TDestinationDictionary Convert (this TSourceDictionary dict, Func converter) where TSourceDictionary : IDictionary where TDestinationDictionary : IDictionary, new() { TDestinationDictionary res = new TDestinationDictionary(); foreach(KeyValuePair kvp in dict) { res[kvp.Key] = converter(kvp.Value); } return res; } public delegate TResult RefFunc(ref T arg); public static RefFunc getProperty(this object obj, Func creator) { return (ref T arg) => { if(arg == null) { arg = creator(); } return arg; }; } public static T getProperty(this object obj, ref T arg, Func creator) { return obj.getProperty(creator)(ref arg); } public static string ToPrintableString(this bool val) { return val ? "Enabled" : "Disabled"; } public static string ToPlainString(this bool val) { return val ? "true" : "false"; } public static string ToPrintableString(this IEnumerable list) { return string.Join(",", (from elem in list select elem.ToString()).ToArray()); } public static string ToDBString(this bool val) { return val ? "1" : "0"; } public static T Safe(this T obj, T defaultValue) { if(obj == null) { return defaultValue; } else { return obj; } } public static HashSet Clone(this HashSet obj) { return new HashSet(obj); } /// /// Note that actions from todoArr can be executed in any order! /// /// /// /// /// public static T Tee(this T obj, params Action[] todoArr) { foreach(Action todo in todoArr) todo(obj); return obj; } public static T Tee(this T obj, Action todo) { todo(); return obj; } private static List GetAttributeArray(this System.Reflection.PropertyInfo property) where TAttribute : Attribute { return new List(from attribute in property.GetCustomAttributes(true) where /*Tie(attribute, obj => Console.WriteLine(obj.GetType().FullName))*/ attribute is TAttribute select (TAttribute)attribute); } public static TAttribute GetAttribute(this System.Reflection.PropertyInfo property) where TAttribute : Attribute { return property.GetAttributeArray().Single(); } public static bool HasAttribute(this System.Reflection.PropertyInfo property) where TAttribute : Attribute { return property.GetAttributeArray().Count > 0; } public static TResult Invoke(this System.Reflection.MethodBase method, object obj, params object[] args) { return (TResult)method.Invoke(obj, args); } public static void Invoke(this System.Reflection.MethodBase method, object obj, params object[] args) { method.Invoke(obj, args); } public static Dictionary Replace(this IDictionary dict, Func Replacer) { return new List>( from kvp in dict select new KeyValuePair(kvp.Key, Replacer(kvp.Value)) ).ToDictionary(); } public static Dictionary Replace(this IDictionary dict, Func Replacer) { return dict.Replace(Replacer); } public static T Single(this IEnumerable list, Predicate checker, Func onNotFound) { try { return list.Single(checker.ToFunc()); } catch(InvalidOperationException) { return onNotFound(); } } public static IEnumerable Enquote(this IEnumerable strings) { return from str in strings select str.Enquote(); } public static TResult Check(this TSource obj, Predicate checker, Func returnOnFail, TResult returnOnSuccess) { if(!checker(obj)) { return returnOnFail(obj); } else { return returnOnSuccess; } } public static TResult Check(this TSource obj, Predicate checker, Func onFail, Func returnOnSuccess) { if(!checker(obj)) { throw onFail(obj); } else { return returnOnSuccess(obj); } } public static void Check(this T obj, Predicate checker, Func onFail) { if(!checker(obj)) { throw onFail(obj); } } public static bool Empty(this IEnumerable list) { return list.Count() == 0; } /// /// Checks arg given against the predicate given; in case of type mismatch returns false /// /// /// /// /// public static bool TypedLoosePredicate(this object arg, Predicate checker) { return (arg is T) && checker((T)arg); } public static Func SafeToStringConvertor() { return obj => obj == null ? "" : obj.ToString(); } public static T Recurse(this T obj, Func step, Predicate checker) { //Debugger.Debug("recurse(" + typeof(T).FullName + ")"); int i=0; while(checker(obj)) { //Debugger.Debug("Iteration " + i.ToString()); obj = step(obj); i++; } //Debugger.Debug("endrecurse(" + typeof(T).Name + ")"); return obj; } public static T[] Slice(this T[] obj, int offset, int length) { if(offset<0) throw new IndexOutOfRangeException(); if(offset+length > obj.Length) throw new IndexOutOfRangeException(); T[] res = new T[length]; Array.Copy(obj, offset, res, 0, length); return res; } public static T[] Slice(this T[] arr, int offset) { return arr.Slice(offset, arr.Length-offset); } public static T TryValues(this T obj, params Func[] trials) { //Debugger.Debug("TryValues(" + typeof(T).FullName + ")"); return new KeyValuePair[]>(obj, trials).Recurse( kvp => new KeyValuePair[]>(kvp.Value[0](), kvp.Value.Slice(1)), kvp => !kvp.Value.Empty() && kvp.Key == null ).Key; } public static IEnumerable Replace(this IEnumerable list, Func replacer) { return from elem in list select replacer(elem); } internal static string ToStringOnFail(this bool test, Lazy onFail) { return test ? "" : onFail(); } public static string Join(this IEnumerable strings, string separator) { return String.Join(separator, strings.ToArray()); } public static IEnumerable GetSorted(this IEnumerable list) { return from elem in list orderby elem select elem; } public static Int64 ToInt64(this decimal number) { return decimal.ToInt64(number); } public static string ToUTCString(this DateTime date) { return date.ToUniversalTime().ToString("u"); } public static IEnumerable ToSequence(this T obj, Func> nextElementsGenerator) where T : class { yield return obj; foreach(var sub in nextElementsGenerator(obj)) { foreach(var subsub in sub.ToSequence(nextElementsGenerator)) { yield return subsub; } } } public static T Last(this List list) { return list[list.Count-1]; } public static IEnumerable Union(this IEnumerable enumerable, params T[] second) { return enumerable.Union((IEnumerable)second); } /// /// Code taken from http://msdn.microsoft.com/en-us/library/system.io.stream.write.aspx /// /// /// public static void WriteTo(this Stream input, Stream output) { const int size = 4096; byte[] bytes = new byte[4096]; int numBytes; while((numBytes = input.Read(bytes, 0, size)) > 0) output.Write(bytes, 0, numBytes); } } }