tsunami
log in
email
password
links
newest items
tag list
syntax reference
tag:time
history
item name
tags
{{ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.IO; using System.Reflection; namespace LinqCheating { class Program { static T CastExact<T>(object obj, T template) { return (T)obj; } static Tuple<MethodInfo[], ConstructorInfo> ConverterPartial(Tuple<Type, Type> tuple) { var propPairs = tuple.Second .GetProperties() .GroupJoin( tuple.First.GetProperties(), o => new { o.Name, o.PropertyType }, i => new { i.Name, i.PropertyType }, (o, ii) => new Tuple<PropertyInfo, PropertyInfo>(ii.FirstOrDefault(), o)); if (propPairs.Any(el => el.First == null)) throw new InvalidCastException(string.Format( "Attempted to cast {0} to {1}; the following properties were missing from {0}:\n" + propPairs .Where(el => el.First == null) .Select(el => string.Format(" {0} {1}", el.Second.PropertyType.Name, el.Second.Name)) .Join("\n"), tuple.First.Name, tuple.Second.Name)); return new Tuple<MethodInfo[], ConstructorInfo>( propPairs.Select(t => t.First.GetGetMethod()).ToArray(), tuple.Second.GetConstructors().Single()); } static Func<Tuple<Type, Type>, Tuple<MethodInfo[], ConstructorInfo>> _converterPartial = Functional.Memoize<Tuple<Type, Type>, Tuple<MethodInfo[], ConstructorInfo>>(ConverterPartial); static T CastPartial<T>(object obj, T template) { var cached = _converterPartial(new Tuple<Type, Type>(obj.GetType(), typeof(T))); return (T)cached.Second.Invoke( cached.First.Select(el => el.Invoke(obj, null)).ToArray()); } static IEnumerable<T> Pull<T>(object obj) { var props = from p in obj.GetType().GetProperties() where p.PropertyType == typeof(T) select p; return props.Select(p => (T)p.GetValue(obj, null)); } static IEnumerable<T> Pull<T>(object obj, T template) { var props = from p in obj.GetType().GetProperties() where p.PropertyType == typeof(T) select p; return props.Select(p => (T)p.GetValue(obj, null)); } static void CheatCastExact(object obj) { var cheated = CastExact(obj, new { A = default(string), B = default(string) }); Console.WriteLine(" " + cheated.B); } static void CheatCastPartial(object obj) { var cheated = CastPartial(obj, new { A = default(string), Q = new { S = default(int), T = default(string) } }); Console.WriteLine(" " + cheated); } static void CheatPull(object obj) { var cheated = Pull<string>(obj); foreach(var s in cheated) Console.WriteLine(" " + s); var other = Pull(obj, new { S = default(int), T = default(string) }); foreach (var v in other) Console.WriteLine(" " + v); } static void Time(string description, int iterations, Action a) { Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) a(); sw.Stop(); // so we can redirect stdout to null if we want Console.Error.WriteLine( "{0,7:0} ticks {1,7:0.000} ms ({2,6}) {3}", sw.Elapsed.Ticks, sw.Elapsed.TotalMilliseconds, iterations, description); } static void Execute<T>(string description, Action<T> a, T arg) { Console.WriteLine(description); Console.WriteLine("input: " + arg); Console.WriteLine("output:"); a(arg); Console.WriteLine(); } static void Main(string[] args) { var w = new { A = "a", B = "b", N = 1, Q = new { S = 1, T = "a" } }; Execute("CheatPull", CheatPull, w); Execute("CheatCastExact", CheatCastExact, new { A = "a", B = "b" }); Execute("CheatCastPartial", CheatCastPartial, w); //Time("CheatCastPartial", 100000, () => CheatCastPartial(w)); Console.SetOut(TextWriter.Null); Time("CheatCastPartial", 100000, () => CheatCastPartial(w)); } } static class Functional { public static string Join(this IEnumerable<string> strings, string delimiter) { return strings.Any() ? string.Join(delimiter, strings as string[] ?? strings.ToArray()) : ""; } public static Func<A, R> Memoize<A, R>(this Func<A, R> f) { var cache = new Dictionary<A, R>(); return Memoize(f, cache); } public static Func<A, R> Memoize<A, R>(this Func<A, R> f, IDictionary<A, R> cache) { return delegate(A a) { R value; if (!cache.TryGetValue(a, out value)) { value = f(a); cache.Add(a, value); } return value; }; } } public class Tuple<T1, T2> { public T1 First { get; private set; } public T2 Second { get; private set; } public Tuple(T1 first, T2 second) { First = first; Second = second; } public override int GetHashCode() { return First.GetHashCode() ^ Second.GetHashCode(); } public override bool Equals(object obj) { var t = obj as Tuple<T1, T2>; return t != null && t.First.Equals(this.First) && t.Second.Equals(this.Second); } public override string ToString() { return string.Format("First: {0} Second: {1}", First, Second); } } } }}
some permissive license goes here
contact