1 #region MIT license 2 // 3 // MIT license 4 // 5 // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 // 25 #endregion 26 27 using System; 28 using System.Reflection; 29 30 namespace DbLinq.Util 31 { 32 /// <summary> 33 /// Types conversion. 34 /// A "smart" extension to System.Convert (at least that's what we hope) 35 /// </summary> 36 #if !MONO_STRICT 37 public 38 #endif 39 static class TypeConvert 40 { ToNumber(object o, Type numberType)41 public static object ToNumber(object o, Type numberType) 42 { 43 if (o.GetType() == numberType) 44 return o; 45 string methodName = string.Format("To{0}", numberType.Name); 46 MethodInfo convertMethod = typeof(Convert).GetMethod(methodName, new[] { o.GetType() }); 47 if (convertMethod != null) 48 return convertMethod.Invoke(null, new[] { o }); 49 throw new InvalidCastException(string.Format("Can't convert type {0} in Convert.{1}()", o.GetType().Name, methodName)); 50 } 51 ToNumber(object o)52 public static U ToNumber<U>(object o) 53 { 54 return (U)ToNumber(o, typeof(U)); 55 } 56 57 /// <summary> 58 /// Returns the default value for a specified type. 59 /// Reflection equivalent of default(T) 60 /// </summary> 61 /// <param name="t"></param> 62 /// <returns></returns> GetDefault(Type t)63 public static object GetDefault(Type t) 64 { 65 if (!t.IsValueType) 66 return null; 67 return Activator.CreateInstance(t); 68 } 69 70 /// <summary> 71 /// Converts a value to an enum 72 /// (work with literals string values and numbers) 73 /// </summary> 74 /// <param name="o">The literal to convert</param> 75 /// <param name="enumType">The target enum type</param> 76 /// <returns></returns> ToEnum(object o, Type enumType)77 public static int ToEnum(object o, Type enumType) 78 { 79 var e = (int)Enum.Parse(enumType, o.ToString()); 80 return e; 81 } 82 ToEnum(object o)83 public static E ToEnum<E>(object o) 84 { 85 return (E)(object)ToEnum(o, typeof(E)); 86 } 87 ToBoolean(object o)88 public static bool ToBoolean(object o) 89 { 90 if (o is bool) 91 return (bool)o; 92 // if it is a string, we may have "T"/"F" or "True"/"False" 93 if (o is string) 94 { 95 // regular literals 96 var lb = (string)o; 97 bool ob; 98 if (bool.TryParse(lb, out ob)) 99 return ob; 100 // alternative literals 101 if (lb == "T" || lb == "F") 102 return lb == "T"; 103 if (lb == "Y" || lb == "N") 104 return lb == "Y"; 105 } 106 return ToNumber<int>(o) != 0; 107 } 108 ToString(object o)109 public static string ToString(object o) 110 { 111 if (o == null) 112 return null; 113 return o.ToString(); 114 } 115 ToChar(object c)116 public static char ToChar(object c) 117 { 118 if (c is char) 119 return (char)c; 120 if (c is string) 121 { 122 var sc = (string)c; 123 if (sc.Length == 1) 124 return sc[0]; 125 } 126 if (c == null) 127 return '\0'; 128 throw new InvalidCastException(string.Format("Can't convert type {0} in GetAsChar()", c.GetType().Name)); 129 } 130 ToGuid(object o)131 public static Guid ToGuid(object o) 132 { 133 if (o is Guid) 134 return (Guid)o; 135 return new Guid(ToString(o)); 136 } 137 To(object o, Type targetType)138 public static object To(object o, Type targetType) 139 { 140 if (targetType.IsNullable()) 141 { 142 if (o == null) 143 return null; 144 return Activator.CreateInstance(targetType, To(o, targetType.GetNullableType())); 145 } 146 if (targetType == typeof(string)) 147 return ToString(o); 148 if (targetType == typeof(bool)) 149 return ToBoolean(o); 150 if (targetType == typeof(char)) 151 return ToChar(o); 152 if (targetType == typeof(byte)) 153 return ToNumber<byte>(o); 154 if (targetType == typeof(sbyte)) 155 return ToNumber<sbyte>(o); 156 if (targetType == typeof(short)) 157 return ToNumber<short>(o); 158 if (targetType == typeof(ushort)) 159 return ToNumber<ushort>(o); 160 if (targetType == typeof(int)) 161 return ToNumber<int>(o); 162 if (targetType == typeof(uint)) 163 return ToNumber<uint>(o); 164 if (targetType == typeof(long)) 165 return ToNumber<long>(o); 166 if (targetType == typeof(ulong)) 167 return ToNumber<ulong>(o); 168 if (targetType == typeof(float)) 169 return ToNumber<float>(o); 170 if (targetType == typeof(double)) 171 return ToNumber<double>(o); 172 if (targetType == typeof(decimal)) 173 return ToNumber<decimal>(o); 174 if (targetType == typeof(DateTime)) 175 return (DateTime)o; 176 if (targetType == typeof(Guid)) 177 return ToGuid(o); 178 if (targetType.IsEnum) 179 return ToEnum(o, targetType); 180 throw new ArgumentException(string.Format("L0117: Unhandled type {0}", targetType)); 181 } 182 To(object o)183 public static T To<T>(object o) 184 { 185 return (T)To(o, typeof(T)); 186 } 187 } 188 } 189