public static BasicTypes GetConversionType(Type innType, Type outType) { if (innType.Implements<IDictionary>() && outType.Implements<IDictionary>()) return BasicTypes.Dictionary; if (innType.Implements<IEnumerable>() && outType.Implements<IEnumerable>() && !innType.IsValueType()) return BasicTypes.List; if (innType.IsValueType() && outType.IsValueType() || TypeExtensions.CanConvert(outType, innType)) return BasicTypes.Convertable; return BasicTypes.ComplexType; }
public static object TryCast(object value, Type targetType) { Type underlyingType = Nullable.GetUnderlyingType(targetType) ?? targetType; #if !NETFX_CORE if(underlyingType.IsEnum && value is string) { #else if(underlyingType.IsEnum() && value is string) { #endif value = Enum.Parse(underlyingType, (string)value, false); } else if( #if !NETFX_CORE value is IConvertible && #else IsConvertableType(value) && #endif !targetType.IsAssignableFrom(value.GetType())) { value = Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture); } #if !NETFX_CORE if(value == null && targetType.IsValueType) #else if(value == null && targetType.IsValueType()) #endif value = Activator.CreateInstance(targetType); return value; }
public static object DeserializeFromString(string reader, Type type, Options options) { var cached = (Func<string, Options, object>)DeserializeFromStringIndirectCache[type]; if (cached == null) { lock (DeserializeFromStreamIndirectCache) { cached = (Func<string, Options, object>)DeserializeFromStringIndirectCache[type]; if (cached == null) { var emit = Emit.NewDynamicMethod(typeof(object), new[] { typeof(string), typeof(Options) }, doVerify: Utils.DoVerify); var mtd = JSONDeserializeFromString.MakeGenericMethod(type); emit.LoadArgument(0); // TextReader emit.LoadArgument(1); // TextReader Options emit.Call(mtd); // type if (type.IsValueType()) { emit.Box(type); // object } emit.Return(); DeserializeFromStringIndirectCache[type] = cached = emit.CreateDelegate<Func<string, Options, object>>(Utils.DelegateOptimizationOptions); } } } return cached(reader, options); }
public static Instruction Create(Type type) { // Boxed enums can be unboxed as their underlying types: switch ((type.IsEnum() ? Enum.GetUnderlyingType(type) : type).GetTypeCode()) { case TypeCode.Boolean: return _Boolean ?? (_Boolean = new NotEqualBoolean()); case TypeCode.SByte: return _SByte ?? (_SByte = new NotEqualSByte()); case TypeCode.Byte: return _Byte ?? (_Byte = new NotEqualByte()); case TypeCode.Char: return _Char ?? (_Char = new NotEqualChar()); case TypeCode.Int16: return _Int16 ?? (_Int16 = new NotEqualInt16()); case TypeCode.Int32: return _Int32 ?? (_Int32 = new NotEqualInt32()); case TypeCode.Int64: return _Int64 ?? (_Int64 = new NotEqualInt64()); case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new NotEqualInt16()); case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new NotEqualInt32()); case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new NotEqualInt64()); case TypeCode.Single: return _Single ?? (_Single = new NotEqualSingle()); case TypeCode.Double: return _Double ?? (_Double = new NotEqualDouble()); case TypeCode.Object: if (!type.IsValueType()) { return _Reference ?? (_Reference = new NotEqualReference()); } // TODO: Nullable<T> throw new NotImplementedException(); default: throw new NotImplementedException(); } }
public static void UnboxIfNeeded(this ILGenerator generator, Type type) { if (type.IsValueType()) generator.Emit(OpCodes.Unbox_Any, type); else generator.Emit(OpCodes.Castclass, type); }
public static object CreateNonNullValue(Type type) { return type.IsValueType() ? CreateObject(type) : type == typeof (string) ? string.Empty : CreateObject(type); }
public static void PushInstance(this ILGenerator generator, Type type) { generator.Emit(OpCodes.Ldarg_0); if (type.IsValueType()) generator.Emit(OpCodes.Unbox, type); else generator.Emit(OpCodes.Castclass, type); }
/// <summary>Checks whether the specified <paramref name='type' /> can be assigned null.</summary> /// <param name='type'>Type to check.</param> /// <returns>true if type is a reference type or a Nullable type; false otherwise.</returns> internal static bool TypeAllowsNull(Type type) { Debug.Assert(type != null, "type != null"); //// This is a copy of WebUtil.TypeAllowsNull from the product. return !type.IsValueType() || IsNullableType(type); }
internal static bool TypeAllowsNull(Type type) { if (type.IsValueType()) { return IsNullableType(type); } return true; }
public static void BoxIfNeeded(this ILGenerator generator, Type type) { if (type.IsValueType()) { generator.Emit(OpCodes.Box, type); } else { generator.Emit(OpCodes.Castclass, type); } }
static LambdaExpression ConvertExpression(Type sourceType, Type destinationType) { bool nullableDestination; var underlyingDestinationType = UnderlyingType(destinationType, out nullableDestination); var convertMethod = typeof(Convert).GetDeclaredMethod("To" + underlyingDestinationType.Name, new[] { sourceType }); var sourceParameter = Parameter(sourceType, "source"); Expression convertCall = Call(convertMethod, sourceParameter); var lambdaBody = nullableDestination && !sourceType.IsValueType() ? Condition(Equal(sourceParameter, Constant(null)), Constant(null, destinationType), ToType(convertCall, destinationType)) : convertCall; return Lambda(lambdaBody, sourceParameter); }
static void EmitTypeConversion(ILGenerator generator, Type castType, bool isContainer) { if (castType == typeof(object)) { } else if (castType.IsValueType()) { generator.Emit(isContainer ? OpCodes.Unbox : OpCodes.Unbox_Any, castType); } else { generator.Emit(OpCodes.Castclass, castType); } }
/// <summary> /// Converts an object at runtime into the specified type. /// </summary> public virtual object Convert(object obj, Type toType) { if (obj == null) { if (!toType.IsValueType()) { return null; } } else { if (toType.IsValueType()) { if (toType == obj.GetType()) { return obj; } } else { if (toType.IsAssignableFrom(obj.GetType())) { return obj; } } } throw Error.InvalidCast(obj != null ? obj.GetType().Name : "(null)", toType.Name); }
public object GetValue(Type targetType) { var stringValue = _underlyingValue as string; if (_underlyingValue == null) { if (targetType.IsValueType() && !(targetType.IsGenericType() && targetType.GetGenericTypeDefinition() == typeof(Nullable<>))) { var valueAsString = string.IsNullOrEmpty(stringValue) ? "<null>" : string.Format("\"{0}\"", _underlyingValue); throw new ArgumentException(string.Format("Cannot convert {0} to {1} (Column: '{2}', Row: {3})", valueAsString, targetType.Name, Header, Row)); } ValueHasBeenUsed = true; return null; } ValueHasBeenUsed = true; if (targetType.IsInstanceOfType(_underlyingValue)) return _underlyingValue; if (targetType.IsEnum() && _underlyingValue is string) return Enum.Parse(targetType, (string)_underlyingValue); if (targetType == typeof(DateTime)) return DateTime.Parse(stringValue); try { return Convert.ChangeType(_underlyingValue, targetType); } catch (InvalidCastException ex) { throw new UnassignableExampleException(string.Format( "{0} cannot be assigned to {1} (Column: '{2}', Row: {3})", _underlyingValue == null ? "<null>" : _underlyingValue.ToString(), targetType.Name, Header, Row), ex, this); } }
/// <summary> /// Emits a load indirect opcode of the appropriate type for a value or object reference. /// Pops a pointer off the evaluation stack, dereferences it and loads /// a value of the specified type. /// </summary> /// <param name = "gen"></param> /// <param name = "type"></param> public static void EmitLoadIndirectOpCodeForType(ILGenerator gen, Type type) { if (type.IsEnum()) { EmitLoadIndirectOpCodeForType(gen, GetUnderlyingTypeOfEnum(type)); return; } if (type.IsByRef) { throw new NotSupportedException("Cannot load ByRef values"); } else if (type.IsPrimitive() && type != typeof(IntPtr)) { var opCode = LdindOpCodesDictionary.Instance[type]; if (opCode == LdindOpCodesDictionary.EmptyOpCode) { throw new ArgumentException("Type " + type + " could not be converted to a OpCode"); } gen.Emit(opCode); } else if (type.IsValueType()) { gen.Emit(OpCodes.Ldobj, type); } else if (type.IsGenericParameter) { gen.Emit(OpCodes.Ldobj, type); } else { gen.Emit(OpCodes.Ldind_Ref); } }
private static bool IsTypeNullable(Type type) { return !type.IsValueType() || (type.IsGenericType() && type.GetGenericTypeDefinition() == typeof(Nullable<>)); }
internal static bool IsCompatibleWith(this Type source, Type target, out bool boxRequired) { boxRequired = false; if (source == target) return true; if (!target.IsValueType()) { boxRequired = source.IsValueType(); return target.IsAssignableFrom(source); } Type st = GetNonNullableType(source); Type tt = GetNonNullableType(target); if (st != source && tt.Equals(st)) return false; TypeCode sc = st.IsEnum() ? TypeCode.Object : st.GetTypeCode(); TypeCode tc = tt.IsEnum() ? TypeCode.Object : tt.GetTypeCode(); switch (sc) { case TypeCode.SByte: switch (tc) { case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.Byte: switch (tc) { case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.Int16: switch (tc) { case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.UInt16: switch (tc) { case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.Int32: switch (tc) { case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.UInt32: switch (tc) { case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.Int64: switch (tc) { case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.UInt64: switch (tc) { case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return true; } break; case TypeCode.Single: switch (tc) { case TypeCode.Single: case TypeCode.Double: return true; } break; default: if (st == tt) return true; break; } return false; }
private static object GetDefault(Type type) { return type.IsValueType() ? Activator.CreateInstance(type) : null; }
internal static bool CanAssign(Type/*!*/ to, Type/*!*/ from) { return to.IsAssignableFrom(from) && (to.IsValueType() == from.IsValueType()); }
/*!*/ public override Expression Convert(DynamicMetaObject/*!*/ metaObject, Type restrictedType, ParameterInfo info, Type/*!*/ toType) { Expression expr = metaObject.Expression; Type fromType = restrictedType ?? expr.Type; // block: if (fromType == typeof(MissingBlockParam)) { Debug.Assert(toType == typeof(BlockParam) || toType == typeof(MissingBlockParam)); return AstUtils.Constant(null); } if (fromType == typeof(BlockParam) && toType == typeof(MissingBlockParam)) { return AstUtils.Constant(null); } // protocol conversions: if (info != null && info.IsDefined(typeof(DefaultProtocolAttribute), false)) { var action = RubyConversionAction.TryGetDefaultConversionAction(Context, toType); if (action != null) { // TODO: inline implicit conversions: return AstUtils.LightDynamic(action, toType, expr); } // Do not throw an exception here to allow generic type parameters to be used with D.P. attribute. // The semantics should be to use DP if available for the current instantiation and ignore it otherwise. } if (restrictedType != null) { if (restrictedType == typeof(DynamicNull)) { if (!toType.IsValueType() || toType.IsGenericType() && toType.GetGenericTypeDefinition() == typeof(Nullable<>)) { return AstUtils.Constant(null, toType); } else if (toType == typeof(bool)) { return AstUtils.Constant(false); } } if (toType.IsAssignableFrom(restrictedType)) { // expr can be converted to restrictedType, which can be converted toType => we can convert expr to toType: return AstUtils.Convert(expr, CompilerHelpers.GetVisibleType(toType)); } // if there is a simple conversion from restricted type, convert the expression to the restricted type and use that conversion: Type visibleRestrictedType = CompilerHelpers.GetVisibleType(restrictedType); if (Converter.CanConvertFrom(metaObject, visibleRestrictedType, toType, false, NarrowingLevel.None, false, false).IsConvertible) { expr = AstUtils.Convert(expr, visibleRestrictedType); } } return Converter.ConvertExpression(expr, toType, _args.RubyContext, _args.MetaContext.Expression, _implicitProtocolConversions); }
internal static BuiltinFunction GetConstructorFunction(Type type, string name) { List<MethodBase> methods = new List<MethodBase>(); bool hasDefaultConstructor = false; foreach (ConstructorInfo ci in type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)) { if (ci.IsPublic) { if (ci.GetParameters().Length == 0) { hasDefaultConstructor = true; } methods.Add(ci); } } if (type.IsValueType() && !hasDefaultConstructor && type != typeof(void)) { try { methods.Add(typeof(ScriptingRuntimeHelpers).GetMethod("CreateInstance", ReflectionUtils.EmptyTypes).MakeGenericMethod(type)); } catch (BadImageFormatException) { // certain types (e.g. ArgIterator) won't survive the above call. // we won't let you create instances of these types. } } if (methods.Count > 0) { return BuiltinFunction.MakeFunction(name, methods.ToArray(), type); } return null; }
internal static Convertibility CanConvertFrom(DynamicMetaObject fromArg, Type/*!*/ fromType, Type/*!*/ toType, bool toNotNullable, NarrowingLevel level, bool explicitProtocolConversions, bool implicitProtocolConversions) { ContractUtils.RequiresNotNull(fromType, "fromType"); ContractUtils.RequiresNotNull(toType, "toType"); var metaConvertible = fromArg as IConvertibleMetaObject; var rubyMetaConvertible = fromArg as IConvertibleRubyMetaObject; // // narrowing level 0: // if (toType == fromType) { return Convertibility.AlwaysConvertible; } if (fromType == typeof(DynamicNull)) { if (toNotNullable) { return Convertibility.NotConvertible; } if (toType.IsGenericType() && toType.GetGenericTypeDefinition() == typeof(Nullable<>)) { return Convertibility.AlwaysConvertible; } if (!toType.IsValueType()) { // null convertible to any reference type: return Convertibility.AlwaysConvertible; } else if (toType == typeof(bool)) { return Convertibility.AlwaysConvertible; } else if (!ProtocolConversionAction.HasDefaultConversion(toType)) { // null not convertible to a value type unless a protocol conversion is allowed: return Convertibility.NotConvertible; } } // blocks: if (fromType == typeof(MissingBlockParam)) { return new Convertibility(toType == typeof(BlockParam) && !toNotNullable, null); } if (fromType == typeof(BlockParam) && toType == typeof(MissingBlockParam)) { return Convertibility.AlwaysConvertible; } if (toType.IsAssignableFrom(fromType)) { return Convertibility.AlwaysConvertible; } if (HasImplicitNumericConversion(fromType, toType)) { return Convertibility.AlwaysConvertible; } if (CompilerHelpers.GetImplicitConverter(fromType, toType) != null) { return Convertibility.AlwaysConvertible; } if (rubyMetaConvertible != null) { return rubyMetaConvertible.IsConvertibleTo(toType, false); } else if (metaConvertible != null) { return new Convertibility(metaConvertible.CanConvertTo(toType, false), null); } // // narrowing level 1: // if (level < NarrowingLevel.One) { return Convertibility.NotConvertible; } if (explicitProtocolConversions && ProtocolConversionAction.HasDefaultConversion(toType)) { return Convertibility.AlwaysConvertible; } // // narrowing level 2: // if (level < NarrowingLevel.Two) { return Convertibility.NotConvertible; } if (HasExplicitNumericConversion(fromType, toType)) { return Convertibility.AlwaysConvertible; } if (CompilerHelpers.GetExplicitConverter(fromType, toType) != null) { return Convertibility.AlwaysConvertible; } if (CompilerHelpers.HasTypeConverter(fromType, toType)) { return Convertibility.AlwaysConvertible; } if (fromType == typeof(char) && toType == typeof(string)) { return Convertibility.AlwaysConvertible; } if (toType == typeof(bool)) { return Convertibility.AlwaysConvertible; } if (rubyMetaConvertible != null) { return rubyMetaConvertible.IsConvertibleTo(toType, true); } else if (metaConvertible != null) { return new Convertibility(metaConvertible.CanConvertTo(toType, true), null); } // // narrowing level 3: // if (level < NarrowingLevel.Three) { return Convertibility.NotConvertible; } if (implicitProtocolConversions && ProtocolConversionAction.HasDefaultConversion(toType)) { return Convertibility.AlwaysConvertible; } // A COM object can potentially be converted to the given interface, but might also be not so use this only as the last resort: if (TypeUtils.IsComObjectType(fromType) && toType.IsInterface()) { return Convertibility.AlwaysConvertible; } return Convertibility.NotConvertible; }
public static object CreateDefaultValue(Type type) { return type.IsValueType() ? CreateObject(type) : null; }
private static bool CompatibleParameterTypes(Type parameter, Type argument) { if (parameter == argument || (!parameter.IsValueType() && !argument.IsValueType() && parameter.IsAssignableFrom(argument))) { return true; } if (parameter.IsByRef && parameter.GetElementType() == argument) { return true; } return false; }
internal static Expression ExplicitConvert(Expression/*!*/ expr, Type/*!*/ fromType, Type/*!*/ toType) { expr = AstUtils.Convert(expr, fromType); if (HasExplicitNumericConversion(fromType, toType)) { // special cases to mimic Ruby behavior precisely: if (fromType == typeof(BigInteger)) { if (toType == typeof(int)) { return Methods.ConvertBignumToFixnum.OpCall(expr); } else if (toType == typeof(double)) { return Methods.ConvertBignumToFloat.OpCall(expr); } } else if (fromType == typeof(double) && toType == typeof(int)) { return Methods.ConvertDoubleToFixnum.OpCall(expr); } return Ast.ConvertChecked(expr, toType); } MethodInfo converter = CompilerHelpers.GetExplicitConverter(fromType, toType); if (converter != null) { return Ast.Call(null, converter, expr); } if (fromType == typeof(char) && toType == typeof(string)) { return Ast.Call(null, fromType.GetMethod("ToString", BindingFlags.Public | BindingFlags.Static), expr); } if (toType == typeof(bool)) { Debug.Assert(fromType != typeof(bool)); return fromType.IsValueType() ? AstUtils.Constant(true) : Ast.NotEqual(expr, AstUtils.Constant(null)); } // TODO: //if (TypeConverter...(fromType, toType)) { // return true; //} return null; }
internal object CoerceType(Type targetType, object value) { bool isNullable = TypeCoercionUtility.IsNullable(targetType); if (value == null) { #if NETFX_CORE if (!allowNullValueTypes && targetType.IsValueType() && !isNullable) #else if (!allowNullValueTypes && targetType.IsValueType && !isNullable) #endif { throw new JsonTypeCoercionException(String.Format(TypeCoercionUtility.ErrorNullValueType, 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 (targetType.IsAssignableFrom(actualType)) { return value; } #if NETFX_CORE if (targetType.IsEnum()) #else if (targetType.IsEnum) #endif { if (value is String) { if (!Enum.IsDefined(targetType, value)) { // if isn't a defined value perhaps it is the JsonName foreach (FieldInfo field in 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 (typeof(IEnumerable).IsAssignableFrom(targetType) && typeof(IEnumerable).IsAssignableFrom(actualType)) { return this.CoerceList(targetType, actualType, (IEnumerable)value); } if (value is String) { if (targetType == typeof(DateTime)) { DateTime date; if (DateTime.TryParse( (string)value, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.RoundtripKind | DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.NoCurrentDateDefault, out date)) { return date; } } else if (targetType == typeof(Guid)) { // try-catch is pointless since will throw upon generic conversion return new Guid((string)value); } else if (targetType == typeof(Char)) { if (((string)value).Length == 1) { return ((string)value)[0]; } } else if (targetType == typeof(Uri)) { Uri uri; if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out uri)) { return uri; } } else if (targetType == typeof(Version)) { // try-catch is pointless since will throw upon generic conversion return new Version((string)value); } } else if (targetType == typeof(TimeSpan)) { return new TimeSpan((long)this.CoerceType(typeof(Int64), value)); } #if !NETFX_CORE 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}", value.GetType().FullName, targetType.FullName), ex); } }
internal Object InstantiateObject(Type objectType, out Dictionary<string, MemberInfo> memberMap) { #if NETFX_CORE if (objectType.IsInterface() || objectType.IsAbstract() || objectType.IsValueType()) #else if (objectType.IsInterface || objectType.IsAbstract || objectType.IsValueType) #endif { throw new JsonTypeCoercionException( String.Format(TypeCoercionUtility.ErrorCannotInstantiate, objectType.FullName)); } #if NETFX_CORE ConstructorInfo ctor = objectType.GetParameterlessConstructor(); #else ConstructorInfo ctor = objectType.GetConstructor(Type.EmptyTypes); #endif if (ctor == null) { throw new JsonTypeCoercionException( String.Format(TypeCoercionUtility.ErrorDefaultCtor, objectType.FullName)); } Object result; try { // always try-catch Invoke() to expose real exception result = ctor.Invoke(null); } catch (TargetInvocationException ex) { if (ex.InnerException != null) { throw new JsonTypeCoercionException(ex.InnerException.Message, ex.InnerException); } throw new JsonTypeCoercionException("Error instantiating " + objectType.FullName, ex); } memberMap = GetMemberMap (objectType); return result; }
public static bool IsNullable(Type t) { if (t.IsValueType()) return IsNullableType(t); return true; }
public static bool HasDefaultConstructor(Type t, bool nonPublic) { if (t.IsValueType()) return true; return (GetDefaultConstructor(t, nonPublic) != null); }
internal static object Convert(IBindingMemberInfo member, Type type, object value) { if (value == null) { if (type.IsValueType() && !type.IsNullableType()) return Activator.CreateInstance(type); return null; } if (type.IsInstanceOfType(value)) return value; #if WPF || ANDROID || TOUCH || WINFORMS || WINDOWS_PHONE || SILVERLIGHT var converter = GetTypeConverter(type, member.Member); if (converter != null && converter.CanConvertFrom(value.GetType())) return converter.ConvertFrom(value); #endif #if PCL_WINRT if (TypeCodeTable.ContainsKey(value.GetType())) #else if (value is IConvertible) #endif return System.Convert.ChangeType(value, type.GetNonNullableType(), CultureInfo.CurrentCulture); if (type == typeof(string)) return value.ToString(); return value; }