/// <summary> /// 对指定类型执行基本的类型转换判断,包括转换为 object 和 null 转换。 /// 基本类型转换失败时,保证 value != null,nonNullableType != null。 /// </summary> /// <param name="value">要转换的对象。</param> /// <param name="conversionType">要返回的对象的类型。</param> /// <param name="nonNullableType"><paramref name="value"/> 对应的 non-nullable-type。</param> /// <returns>如果基本类型转换成功,则为 <c>true</c>;否则为 <c>false</c>。</returns> private static bool BasicChangeType(ref object value, Type conversionType, out Type nonNullableType) { CommonExceptions.CheckArgumentNull(conversionType, "conversionType"); if (conversionType.IsByRef) { conversionType = conversionType.GetElementType(); } // 总是可以转换为 Object。 if (conversionType == typeof(object)) { nonNullableType = null; return true; } // value 为 null 的情况。 bool nullableCType = TypeExt.IsNullableType(conversionType, out nonNullableType); if (value == null) { if (conversionType.IsValueType && !nullableCType) { throw CommonExceptions.CannotCastNullToValueType(); } return true; } return false; }
/// <summary> /// 返回指定类型的对象,其值等效于指定对象。 /// </summary> /// <typeparam name="TOutput">要转换到的类型。</typeparam> /// <param name="value">要将 <paramref name="value"/> 转换的对象。</param> /// <returns>一个对象,其类型为 <typeparamref name="TOutput"/>, /// 并且其值等效于 <paramref name="value"/>。</returns> /// <remarks>尽可能使用泛型方法 <see cref="ChangeType{TInput,TOutput}"/>,这样可以避免额外的类型转换。</remarks> /// <exception cref="InvalidCastException"><paramref name="value"/> 为 <c>null</c>, /// 而且 <typeparamref name="TOutput"/> 是值类型。</exception> /// <exception cref="InvalidCastException">不支持此转换。</exception> public static TOutput ChangeType <TOutput>(object value) { if (value == null) { if (typeof(TOutput).IsValueType) { throw CommonExceptions.CannotCastNullToValueType(); } return(default(TOutput)); } var converter = GetConverter(value.GetType(), typeof(TOutput)); if (converter == null) { throw CommonExceptions.InvalidCast(value.GetType(), typeof(TOutput)); } return((TOutput)converter(value)); }
/// <summary> /// 返回指定类型的对象,其值等效于指定对象。 /// </summary> /// <param name="value">要转换的对象。</param> /// <param name="outputType">要将 <paramref name="value"/> 转换到的类型。</param> /// <returns>一个对象,其类型为 <paramref name="outputType"/>, /// 并且其值等效于 <paramref name="value"/>。</returns> /// <remarks>尽可能使用泛型方法 <see cref="ChangeType{TInput,TOutput}"/>,这样可以避免额外的类型转换。</remarks> /// <exception cref="ArgumentNullException"><paramref name="outputType"/> 为 <c>null</c>。</exception> /// <exception cref="InvalidCastException"><paramref name="value"/> 为 <c>null</c>, /// 而且 <paramref name="outputType"/> 是值类型。</exception> /// <exception cref="InvalidCastException">不支持此转换。</exception> public static object ChangeType(object value, Type outputType) { CommonExceptions.CheckArgumentNull(outputType, nameof(outputType)); Contract.EndContractBlock(); if (value == null) { if (outputType.IsValueType) { throw CommonExceptions.CannotCastNullToValueType(); } return(null); } var converter = GetConverter(value.GetType(), outputType); if (converter == null) { throw CommonExceptions.InvalidCast(value.GetType(), outputType); } return(converter(value)); }