Created
November 29, 2016 10:41
-
-
Save KANekT/d94630fe220869e737a91905aeb8eb8d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class AccessorCache | |
{ | |
private static readonly Hashtable Accessors = new Hashtable(); | |
private static readonly Hashtable CallSites = new Hashtable(); | |
private static CallSite<Func<CallSite, object, object>> GetCallSiteLocked(string name) | |
{ | |
var callSite = (CallSite<Func<CallSite, object, object>>)CallSites[name]; | |
if (callSite == null) | |
{ | |
CallSites[name] = callSite = CallSite<Func<CallSite, object, object>>.Create( | |
Binder.GetMember(CSharpBinderFlags.None, name, typeof(AccessorCache), | |
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })); | |
} | |
return callSite; | |
} | |
internal static Func<dynamic, object> GetAccessor(string name) | |
{ | |
var accessor = (Func<dynamic, object>)Accessors[name]; | |
if (accessor != null) | |
return accessor; | |
lock (Accessors) | |
{ | |
accessor = (Func<dynamic, object>)Accessors[name]; | |
if (accessor != null) | |
return accessor; | |
if (name.IndexOf('.') >= 0) | |
{ | |
var props = name.Split('.'); | |
var arr = props.Select(GetCallSiteLocked).ToArray(); | |
accessor = target => | |
{ | |
var val = (object)target; | |
return arr.Aggregate(val, (current, cs) => cs.Target(cs, current)); | |
}; | |
} | |
else | |
{ | |
var callSite = GetCallSiteLocked(name); | |
accessor = target => callSite.Target(callSite, target); | |
} | |
Accessors[name] = accessor; | |
} | |
return accessor; | |
} | |
public static OrderEnum ToOrder(this string source) | |
{ | |
return (string.IsNullOrEmpty(source) || source == "asc") ? OrderEnum.Asc : OrderEnum.Desc; | |
} | |
public static IOrderedEnumerable<dynamic> Order(this IEnumerable<dynamic> source, string property, OrderEnum direction = OrderEnum.Asc) | |
{ | |
return direction == OrderEnum.Asc ? source.OrderBy(GetAccessor(property), Comparer<object>.Default) : source.OrderByDescending(GetAccessor(property), Comparer<object>.Default); | |
} | |
public static IOrderedEnumerable<dynamic> OrderBy(this IEnumerable<dynamic> source, string property) | |
{ | |
return source.OrderBy(GetAccessor(property), Comparer<object>.Default); | |
} | |
public static IOrderedEnumerable<dynamic> OrderByDescending(this IEnumerable<dynamic> source, string property) | |
{ | |
return source.OrderByDescending(GetAccessor(property), Comparer<object>.Default); | |
} | |
public static IOrderedEnumerable<dynamic> Then(this IOrderedEnumerable<dynamic> source, string property, OrderEnum direction = OrderEnum.Asc) | |
{ | |
return direction == OrderEnum.Asc ? source.ThenBy(GetAccessor(property), Comparer<object>.Default) : source.ThenByDescending(GetAccessor(property), Comparer<object>.Default); | |
} | |
public static IOrderedEnumerable<dynamic> ThenBy(this IOrderedEnumerable<dynamic> source, string property) | |
{ | |
return source.ThenBy(GetAccessor(property), Comparer<object>.Default); | |
} | |
public static IOrderedEnumerable<dynamic> ThenByDescending(this IOrderedEnumerable<dynamic> source, string property) | |
{ | |
return source.ThenByDescending(GetAccessor(property), Comparer<object>.Default); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment