using System; using System.Linq.Expressions; namespace UniJSON { struct GenericCast { public static T Null() { if (typeof(T).IsClass) { return default(T); } else { throw new MsgPackTypeException("can not null"); } } delegate T CastFunc(S value); static CastFunc s_cast; delegate Func ConstFuncCreator(S value); static ConstFuncCreator s_const; public static Func Const(S value) { if (s_const == null) { s_const = new ConstFuncCreator(GenericCast.CreateConst()); } return s_const(value); } public static T Cast(S value) { if (s_cast == null) { s_cast = new CastFunc(GenericCast.CreateCast()); } return s_cast(value); } } static class GenericCast { public static Func CreateCast() { if (typeof(S) == typeof(T)) { // through var src = Expression.Parameter(typeof(S), "src"); var lambda = Expression.Lambda(src, src); return (Func)lambda.Compile(); } else { // cast var src = Expression.Parameter(typeof(S), "src"); var cast = Expression.Convert(src, typeof(T)); var lambda = Expression.Lambda(cast, src); return (Func)lambda.Compile(); } } public static Func> CreateConst() { var src = Expression.Parameter(typeof(S), "src"); var convert = Expression.Convert(src, typeof(T)); var lambda = (Func)Expression.Lambda(convert, src).Compile(); return s => { var t = lambda(s); return () => t; }; } } }