using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Reflection.Emit; namespace Bowin.Common.Utility { public static class WebExtensions { public static T ParseTo(this string value) { if (Parser.ParseMethod != null) return Parser.ParseMethod(value); throw new NotSupportedException(); } public static bool TryParseTo(this string value, out T result) { if (Parser.TryParseMethod != null) { return Parser.TryParseMethod(value, out result); } throw new NotSupportedException(); } public static Nullable ParseStrTo(this string value) where T : struct { if (value == null) return null; if (Parser.TryParseMethod != null) { T result; if (Parser.TryParseMethod(value, out result)) { return result; } else { return null; } } throw new NotSupportedException(); } static WebExtensions() { Parser.ParseMethod = short.Parse; Parser.ParseMethod = int.Parse; Parser.ParseMethod = long.Parse; Parser.ParseMethod = byte.Parse; Parser.ParseMethod = ushort.Parse; Parser.ParseMethod = uint.Parse; Parser.ParseMethod = ulong.Parse; Parser.ParseMethod = sbyte.Parse; Parser.ParseMethod = float.Parse; Parser.ParseMethod = double.Parse; Parser.ParseMethod = decimal.Parse; Parser.ParseMethod = bool.Parse; Parser.ParseMethod = DateTime.Parse; Parser.ParseMethod = TimeSpan.Parse; Parser.ParseMethod = Guid.Parse; Parser.TryParseMethod = short.TryParse; Parser.TryParseMethod = int.TryParse; Parser.TryParseMethod = long.TryParse; Parser.TryParseMethod = byte.TryParse; Parser.TryParseMethod = ushort.TryParse; Parser.TryParseMethod = uint.TryParse; Parser.TryParseMethod = ulong.TryParse; Parser.TryParseMethod = sbyte.TryParse; Parser.TryParseMethod = float.TryParse; Parser.TryParseMethod = double.TryParse; Parser.TryParseMethod = decimal.TryParse; Parser.TryParseMethod = bool.TryParse; Parser.TryParseMethod = DateTime.TryParse; Parser.TryParseMethod = TimeSpan.TryParse; Parser.TryParseMethod = Guid.TryParse; } private class Parser { public delegate T ParseMethodDelegate(string value); public delegate bool TryParseMethodDelegate(string value, out T result); private static bool noParseMethod = false; private static ParseMethodDelegate _parseMethod; public static ParseMethodDelegate ParseMethod { get { if (_parseMethod != null) return _parseMethod; if (noParseMethod) return null; var method = typeof(T).GetMethod("Parse", new Type[] { typeof(string) }); if (method != null && (method.Attributes & MethodAttributes.Static) != 0) { DynamicMethod dynamicMethod = new DynamicMethod(typeof(T).FullName + "_Parse", typeof(T), new Type[] { typeof(string) }); var il = dynamicMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.EmitCall(OpCodes.Call, method, null); il.Emit(OpCodes.Ret); return _parseMethod = (Parser.ParseMethodDelegate)dynamicMethod.CreateDelegate(typeof(Parser.ParseMethodDelegate)); } noParseMethod = true; return null; } set { _parseMethod = value; } } private static bool noTryParseMethod = false; private static TryParseMethodDelegate _tryParseMethod; public static TryParseMethodDelegate TryParseMethod { get { if (_tryParseMethod != null) return _tryParseMethod; if (noTryParseMethod) return null; MethodInfo tryParseMethod = typeof(T).GetMethod("TryParse", new Type[] { typeof(string), Type.GetType(typeof(T).FullName + "&") }); if (tryParseMethod != null) { DynamicMethod tryParseDm = new DynamicMethod("TryParse", typeof(bool), new Type[] { typeof(string), Type.GetType(typeof(T).FullName + "&") }, typeof(Parser), false); ILGenerator tryParseIl = tryParseDm.GetILGenerator(); tryParseIl.Emit(OpCodes.Ldarg_0); tryParseIl.Emit(OpCodes.Ldarg_1); tryParseIl.Emit(OpCodes.Call, tryParseMethod); tryParseIl.Emit(OpCodes.Ret); return _tryParseMethod = (TryParseMethodDelegate)tryParseDm.CreateDelegate(typeof(TryParseMethodDelegate)); } noTryParseMethod = true; return null; } set { _tryParseMethod = value; } } } } }