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