//------------------------------------------------------ // // Internal static API // //------------------------------------------------------ // static constructor - returns a ValueConverter suitable for converting between // the source and target. The flag indicates whether targetToSource // conversions are actually needed. // if no Converter is needed, return DefaultValueConverter.ValueConverterNotNeeded marker. // if unable to create a DefaultValueConverter, return null to indicate error. internal static IValueConverter Create(Type sourceType, Type targetType, bool targetToSource, DataBindEngine engine) { TypeConverter typeConverter; Type innerType; bool canConvertTo, canConvertFrom; bool sourceIsNullable = false; bool targetIsNullable = false; // sometimes, no conversion is necessary if (sourceType == targetType || (!targetToSource && targetType.IsAssignableFrom(sourceType))) { return(ValueConverterNotNeeded); } // the type convert for System.Object is useless. It claims it can // convert from string, but then throws an exception when asked to do // so. So we work around it. if (targetType == typeof(object)) { // The sourceType here might be a Nullable type: consider using // NullableConverter when appropriate. (uncomment following lines) //Type innerType = Nullable.GetUnderlyingType(sourceType); //if (innerType != null) //{ // return new NullableConverter(new ObjectTargetConverter(innerType), // innerType, targetType, true, false); //} // BUG: 1109257 ObjectTargetConverter is not the best converter possible. return(new ObjectTargetConverter(sourceType, engine)); } else if (sourceType == typeof(object)) { // The targetType here might be a Nullable type: consider using // NullableConverter when appropriate. (uncomment following lines) //Type innerType = Nullable.GetUnderlyingType(targetType); // if (innerType != null) // { // return new NullableConverter(new ObjectSourceConverter(innerType), // sourceType, innerType, false, true); // } // BUG: 1109257 ObjectSourceConverter is not the best converter possible. return(new ObjectSourceConverter(targetType, engine)); } // use System.Convert for well-known base types if (SystemConvertConverter.CanConvert(sourceType, targetType)) { return(new SystemConvertConverter(sourceType, targetType)); } // Need to check for nullable types first, since NullableConverter is a bit over-eager; // TypeConverter for Nullable can convert e.g. Nullable<DateTime> to string // but it ends up doing a different conversion than the TypeConverter for the // generic's inner type, e.g. bug 1361977 innerType = Nullable.GetUnderlyingType(sourceType); if (innerType != null) { sourceType = innerType; sourceIsNullable = true; } innerType = Nullable.GetUnderlyingType(targetType); if (innerType != null) { targetType = innerType; targetIsNullable = true; } if (sourceIsNullable || targetIsNullable) { // single-level recursive call to try to find a converter for basic value types return(Create(sourceType, targetType, targetToSource, engine)); } // special case for converting IListSource to IList if (typeof(IListSource).IsAssignableFrom(sourceType) && targetType.IsAssignableFrom(typeof(IList))) { return(new ListSourceConverter()); } // Interfaces are best handled on a per-instance basis. The type may // not implement the interface, but an instance of a derived type may. if (sourceType.IsInterface || targetType.IsInterface) { return(new InterfaceConverter(sourceType, targetType)); } // try using the source's type converter typeConverter = GetConverter(sourceType); canConvertTo = (typeConverter != null) ? typeConverter.CanConvertTo(targetType) : false; canConvertFrom = (typeConverter != null) ? typeConverter.CanConvertFrom(targetType) : false; if ((canConvertTo || targetType.IsAssignableFrom(sourceType)) && (!targetToSource || canConvertFrom || sourceType.IsAssignableFrom(targetType))) { return(new SourceDefaultValueConverter(typeConverter, sourceType, targetType, targetToSource && canConvertFrom, canConvertTo, engine)); } // if that doesn't work, try using the target's type converter typeConverter = GetConverter(targetType); canConvertTo = (typeConverter != null) ? typeConverter.CanConvertTo(sourceType) : false; canConvertFrom = (typeConverter != null) ? typeConverter.CanConvertFrom(sourceType) : false; if ((canConvertFrom || targetType.IsAssignableFrom(sourceType)) && (!targetToSource || canConvertTo || sourceType.IsAssignableFrom(targetType))) { return(new TargetDefaultValueConverter(typeConverter, sourceType, targetType, canConvertFrom, targetToSource && canConvertTo, engine)); } // nothing worked, give up return(null); }
// Token: 0x060074D2 RID: 29906 RVA: 0x00216A6C File Offset: 0x00214C6C internal static IValueConverter Create(Type sourceType, Type targetType, bool targetToSource, DataBindEngine engine) { bool flag = false; bool flag2 = false; if (sourceType == targetType || (!targetToSource && targetType.IsAssignableFrom(sourceType))) { return(DefaultValueConverter.ValueConverterNotNeeded); } if (targetType == typeof(object)) { return(new ObjectTargetConverter(sourceType, engine)); } if (sourceType == typeof(object)) { return(new ObjectSourceConverter(targetType, engine)); } if (SystemConvertConverter.CanConvert(sourceType, targetType)) { return(new SystemConvertConverter(sourceType, targetType)); } Type underlyingType = Nullable.GetUnderlyingType(sourceType); if (underlyingType != null) { sourceType = underlyingType; flag = true; } underlyingType = Nullable.GetUnderlyingType(targetType); if (underlyingType != null) { targetType = underlyingType; flag2 = true; } if (flag || flag2) { return(DefaultValueConverter.Create(sourceType, targetType, targetToSource, engine)); } if (typeof(IListSource).IsAssignableFrom(sourceType) && targetType.IsAssignableFrom(typeof(IList))) { return(new ListSourceConverter()); } if (sourceType.IsInterface || targetType.IsInterface) { return(new InterfaceConverter(sourceType, targetType)); } TypeConverter converter = DefaultValueConverter.GetConverter(sourceType); bool flag3 = converter != null && converter.CanConvertTo(targetType); bool flag4 = converter != null && converter.CanConvertFrom(targetType); if ((flag3 || targetType.IsAssignableFrom(sourceType)) && (!targetToSource || flag4 || sourceType.IsAssignableFrom(targetType))) { return(new SourceDefaultValueConverter(converter, sourceType, targetType, targetToSource && flag4, flag3, engine)); } converter = DefaultValueConverter.GetConverter(targetType); flag3 = (converter != null && converter.CanConvertTo(sourceType)); flag4 = (converter != null && converter.CanConvertFrom(sourceType)); if ((flag4 || targetType.IsAssignableFrom(sourceType)) && (!targetToSource || flag3 || sourceType.IsAssignableFrom(targetType))) { return(new TargetDefaultValueConverter(converter, sourceType, targetType, flag4, targetToSource && flag3, engine)); } return(null); }