public static MethodInfo GetMethod (Type type, MethodInfo method) { if (!IsValidGetMethodType (type)) throw new ArgumentException ("type is not TypeBuilder but " + type.GetType (), "type"); if (type is TypeBuilder && type.ContainsGenericParameters) type = type.MakeGenericType (type.GetGenericArguments ()); if (!type.IsGenericType) throw new ArgumentException ("type is not a generic type", "type"); if (!method.DeclaringType.IsGenericTypeDefinition) throw new ArgumentException ("method declaring type is not a generic type definition", "method"); if (method.DeclaringType != type.GetGenericTypeDefinition ()) throw new ArgumentException ("method declaring type is not the generic type definition of type", "method"); if (method == null) throw new NullReferenceException (); //MS raises this instead of an ArgumentNullException MethodInfo res = type.GetMethod (method); if (res == null) throw new ArgumentException (String.Format ("method {0} not found in type {1}", method.Name, type)); return res; }
internal object CoerceType(Type targetType, object value) { bool isNullable = TypeCoercionUtility.IsNullable(targetType); if (value == null) { if (!allowNullValueTypes && TypeCoercionUtility.GetTypeInfo(targetType).IsValueType && !isNullable) { throw new JsonTypeCoercionException(String.Format(TypeCoercionUtility.ErrorNullValueType, new System.Object[] {targetType.FullName})); } return value; } if (isNullable) { // nullable types have a real underlying struct Type[] genericArgs = targetType.GetGenericArguments(); if (genericArgs.Length == 1) { targetType = genericArgs[0]; } } Type actualType = value.GetType(); if (TypeCoercionUtility.GetTypeInfo(targetType).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(actualType))) { return value; } if (TypeCoercionUtility.GetTypeInfo(targetType).IsEnum) { if (value is String) { if (!Enum.IsDefined(targetType, value)) { // if isn't a defined value perhaps it is the JsonName foreach (FieldInfo field in TypeCoercionUtility.GetTypeInfo(targetType).GetFields()) { string jsonName = JsonNameAttribute.GetJsonName(field); if (((string)value).Equals(jsonName)) { value = field.Name; break; } } } return Enum.Parse(targetType, (string)value); } else { value = this.CoerceType(Enum.GetUnderlyingType(targetType), value); return Enum.ToObject(targetType, value); } } if (value is IDictionary) { Dictionary<string, MemberInfo> memberMap; return this.CoerceType(targetType, (IDictionary)value, out memberMap); } if (TypeCoercionUtility.GetTypeInfo(typeof(IEnumerable)).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(targetType)) && TypeCoercionUtility.GetTypeInfo(typeof(IEnumerable)).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(actualType))) { return this.CoerceList(targetType, actualType, (IEnumerable)value); } if (value is String) { if (Type.Equals (targetType, typeof(DateTime))) { DateTime date; if (DateTime.TryParse( (string)value, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.RoundtripKind | DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.NoCurrentDateDefault, out date)) { return date; } } else if (Type.Equals (targetType, typeof(Guid))) { // try-catch is pointless since will throw upon generic conversion return new Guid((string)value); } else if (Type.Equals (targetType, typeof(Char))) { if (((string)value).Length == 1) { return ((string)value)[0]; } } else if (Equals (targetType, typeof(Uri))) { Uri uri; if (Uri.TryCreate ((string)value, UriKind.RelativeOrAbsolute, out uri)) { return uri; } } else if (Type.Equals (targetType, typeof(Version))) { // try-catch is pointless since will throw upon generic conversion return new Version ((string)value); } } else if (Type.Equals (targetType, typeof(TimeSpan))) { return new TimeSpan ((long)this.CoerceType (typeof(Int64), value)); } if (targetType == typeof(int)) { unchecked { if (value is long) { value = (int)((long)value % int.MaxValue); } else if (!(value is string)) { value = Convert.ToInt32(value); } } } #if !WINPHONE_8 TypeConverter converter = TypeDescriptor.GetConverter(targetType); if (converter.CanConvertFrom(actualType)) { return converter.ConvertFrom(value); } converter = TypeDescriptor.GetConverter(actualType); if (converter.CanConvertTo(targetType)) { return converter.ConvertTo(value, targetType); } #endif try { // fall back to basics return Convert.ChangeType(value, targetType); } catch (Exception ex) { throw new JsonTypeCoercionException( String.Format("Error converting {0} to {1}", new System.Object[] {value.GetType().FullName, targetType.FullName}), ex); } }
static bool IsValidGetMethodType (Type type) { if (type is TypeBuilder || type is MonoGenericClass) return true; /*GetMethod() must work with TypeBuilders after CreateType() was called.*/ if (type.Module is ModuleBuilder) return true; if (type.IsGenericParameter) return false; Type[] inst = type.GetGenericArguments (); if (inst == null) return false; for (int i = 0; i < inst.Length; ++i) { if (IsValidGetMethodType (inst [i])) return true; } return false; }