///// <summary> ///// 变更类型 ///// </summary> ///// <param name="value">值</param> ///// <param name="type">类型</param> //public static object ChangeType(string value, Type type) //{ // object obj = null; // var nullableType = Nullable.GetUnderlyingType(type); // try // { // if (nullableType != null) // { // if (value == null) // obj = null; // else // obj = OtherChangeType(value, type); // } // else if (typeof(Enum).IsAssignableFrom(type)) // { // obj = Enum.Parse(type, value); // } // else // { // obj = Convert.ChangeType(value, type); // } // return obj; // } // catch // { // return default; // } //} /// <summary> /// 变更类型 /// </summary> /// <param name="value">值</param> /// <param name="type">类型</param> /// <param name="cell">单元格</param> public static object ChangeType(object value, Type type, ICell cell) { try { if (value == null && type.IsGenericType) { return(Activator.CreateInstance(type)); } if (value == null || string.IsNullOrWhiteSpace(value.ToString())) { return(null); } if (type == value.GetType()) { return(value); } if (type.IsEnum) { if (value is string) { return(Enum.Parse(type, value as string)); } else { return(Enum.ToObject(type, value)); } } if (!type.IsInterface && type.IsGenericType) { Type innerType = type.GetGenericArguments()[0]; object innerValue = ChangeType(value, innerType, cell); return(Activator.CreateInstance(type, new object[] { innerValue })); } if (value is string && type == typeof(Guid)) { return(new Guid(value as string)); } if (value is string && type == typeof(Version)) { return(new Version(value as string)); } if (!(value is IConvertible)) { return(value); } return(Convert.ChangeType(value, type)); } catch (Exception ex) { throw new OfficeDataConvertException($"值转换失败。输入值为: {value}, 目标类型为: {type.FullName}", ex) { PrimitiveType = value.GetType(), TargetType = type, Value = value, RowIndex = cell.RowIndex + 1, ColumnIndex = cell.ColumnIndex + 1, Name = cell.Name, }; } }
public EnumOrString(string stringValue) { Contract.Requires(!string.IsNullOrWhiteSpace(stringValue)); ulong[] values; string[] names; GetValuesAndNames(out values, out names, true, true); object enumValue = null; int count = values.Length; Contract.Assert(count == names.Length); for (int i = 0; i < count; i++) { string name = names[i]; if (name != stringValue) { continue; } ulong value = values[i]; enumValue = SystemEnum.ToObject(s_enumType, value); break; } if (enumValue != null) { m_enum = (T)enumValue; m_string = null; } else { m_enum = default(T); m_string = stringValue; } }
private static (object?, InvalidOperationException?) TryConvertObject(string context, object?val, Type targetType) { var targetIsNullable = targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable <>); // Note: 'null's can enter the system as the representation of an 'unknown' value. // Before calling 'Convert' we will have already lifted the 'IsKnown' bit out, but we // will be passing null around as a value. if (val == null) { if (targetIsNullable) { // A 'null' value coerces to a nullable null. return(null, null); } if (targetType.IsValueType) { return(Activator.CreateInstance(targetType), null); } // for all other types, can just return the null value right back out as a legal // reference type value. return(null, null); } // We're not null and we're converting to Nullable<T>, just convert our value to be a T. if (targetIsNullable) { return(TryConvertObject(context, val, targetType.GenericTypeArguments.Single())); } if (targetType == typeof(string)) { return(TryEnsureType <string>(context, val)); } if (targetType == typeof(bool)) { return(TryEnsureType <bool>(context, val)); } if (targetType == typeof(double)) { return(TryEnsureType <double>(context, val)); } if (targetType == typeof(int)) { var(d, exception) = TryEnsureType <double>(context, val); if (exception != null) { return(null, exception); } return((int)d, exception); } if (targetType == typeof(object)) { return(val, null); } if (targetType == typeof(Asset)) { return(TryEnsureType <Asset>(context, val)); } if (targetType == typeof(Archive)) { return(TryEnsureType <Archive>(context, val)); } if (targetType == typeof(AssetOrArchive)) { return(TryEnsureType <AssetOrArchive>(context, val)); } if (targetType == typeof(JsonElement)) { return(TryConvertJsonElement(context, val)); } if (targetType.IsSubclassOf(typeof(Resource)) || targetType == typeof(Resource)) { return(TryEnsureType <Resource>(context, val)); } if (targetType.IsEnum) { var underlyingType = targetType.GetEnumUnderlyingType(); var(value, exception) = TryConvertObject(context, val, underlyingType); if (exception != null || value is null) { return(null, exception); } return(Enum.ToObject(targetType, value), null); } if (targetType.IsValueType && targetType.GetCustomAttribute <EnumTypeAttribute>() != null) { var valType = val.GetType(); if (valType != typeof(string) && valType != typeof(double)) { return(null, new InvalidOperationException( $"Expected {typeof(string).FullName} or {typeof(double).FullName} but got {valType.FullName} deserializing {context}")); } var enumTypeConstructor = targetType.GetConstructor( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { valType }, null); if (enumTypeConstructor == null) { return(null, new InvalidOperationException( $"Expected target type {targetType.FullName} to have a constructor with a single {valType.FullName} parameter.")); } return(enumTypeConstructor.Invoke(new[] { val }), null); } if (targetType.IsConstructedGenericType) { if (targetType.GetGenericTypeDefinition() == typeof(Union <,>)) { return(TryConvertOneOf(context, val, targetType)); } if (targetType.GetGenericTypeDefinition() == typeof(ImmutableArray <>)) { return(TryConvertArray(context, val, targetType)); } if (targetType.GetGenericTypeDefinition() == typeof(ImmutableDictionary <,>)) { return(TryConvertDictionary(context, val, targetType)); } throw new InvalidOperationException( $"Unexpected generic target type {targetType.FullName} when deserializing {context}"); } if (targetType.GetCustomAttribute <OutputTypeAttribute>() == null) { return(null, new InvalidOperationException( $"Unexpected target type {targetType.FullName} when deserializing {context}")); } var constructor = GetPropertyConstructor(targetType); if (constructor == null) { return(null, new InvalidOperationException( $"Expected target type {targetType.FullName} to have [{nameof(OutputConstructorAttribute)}] constructor when deserializing {context}")); } var(dictionary, tempException) = TryEnsureType <ImmutableDictionary <string, object> >(context, val); if (tempException != null) { return(null, tempException); } var constructorParameters = constructor.GetParameters(); var arguments = new object?[constructorParameters.Length]; for (int i = 0, n = constructorParameters.Length; i < n; i++) { var parameter = constructorParameters[i]; // Note: TryGetValue may not find a value here. That can happen for things like // unknown vals. That's ok. We'll pass that through to 'Convert' and will get the // default value needed for the parameter type. dictionary !.TryGetValue(parameter.Name !, out var argValue); var(temp, tempException1) = TryConvertObject($"{targetType.FullName}({parameter.Name})", argValue, parameter.ParameterType); if (tempException1 != null) { return(null, tempException1); } arguments[i] = temp; } return(constructor.Invoke(arguments), null); }
public static TEnum Parse <TEnum>(Int32 value) where TEnum : struct { TEnum result = (TEnum)Enum.ToObject(typeof(TEnum), value); return(result); }
// Special coersion rules for primitives, enums and pointer. private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(object srcObject, EETypePtr srcEEType, EETypePtr dstEEType, CheckArgumentSemantics semantics, out object?dstObject) { if (semantics == CheckArgumentSemantics.SetFieldDirect && (srcEEType.IsEnum || dstEEType.IsEnum)) { dstObject = null; return(CreateChangeTypeException(srcEEType, dstEEType, semantics)); } if (dstEEType.IsPointer) { Exception exception = ConvertPointerIfPossible(srcObject, srcEEType, dstEEType, semantics, out IntPtr dstIntPtr); if (exception != null) { dstObject = null; return(exception); } dstObject = dstIntPtr; return(null); } if (!(srcEEType.IsPrimitive && dstEEType.IsPrimitive)) { dstObject = null; return(CreateChangeTypeException(srcEEType, dstEEType, semantics)); } CorElementType dstCorElementType = dstEEType.CorElementType; if (!srcEEType.CorElementTypeInfo.CanWidenTo(dstCorElementType)) { dstObject = null; return(CreateChangeTypeArgumentException(srcEEType, dstEEType)); } switch (dstCorElementType) { case CorElementType.ELEMENT_TYPE_BOOLEAN: bool boolValue = Convert.ToBoolean(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, boolValue ? 1 : 0) : boolValue; break; case CorElementType.ELEMENT_TYPE_CHAR: char charValue = Convert.ToChar(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, charValue) : charValue; break; case CorElementType.ELEMENT_TYPE_I1: sbyte sbyteValue = Convert.ToSByte(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, sbyteValue) : sbyteValue; break; case CorElementType.ELEMENT_TYPE_I2: short shortValue = Convert.ToInt16(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, shortValue) : shortValue; break; case CorElementType.ELEMENT_TYPE_I4: int intValue = Convert.ToInt32(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, intValue) : intValue; break; case CorElementType.ELEMENT_TYPE_I8: long longValue = Convert.ToInt64(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, longValue) : longValue; break; case CorElementType.ELEMENT_TYPE_U1: byte byteValue = Convert.ToByte(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, byteValue) : byteValue; break; case CorElementType.ELEMENT_TYPE_U2: ushort ushortValue = Convert.ToUInt16(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, ushortValue) : ushortValue; break; case CorElementType.ELEMENT_TYPE_U4: uint uintValue = Convert.ToUInt32(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, uintValue) : uintValue; break; case CorElementType.ELEMENT_TYPE_U8: ulong ulongValue = Convert.ToUInt64(srcObject); dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, (long)ulongValue) : ulongValue; break; case CorElementType.ELEMENT_TYPE_R4: if (srcEEType.CorElementType == CorElementType.ELEMENT_TYPE_CHAR) { dstObject = (float)(char)srcObject; } else { dstObject = Convert.ToSingle(srcObject); } break; case CorElementType.ELEMENT_TYPE_R8: if (srcEEType.CorElementType == CorElementType.ELEMENT_TYPE_CHAR) { dstObject = (double)(char)srcObject; } else { dstObject = Convert.ToDouble(srcObject); } break; default: Debug.Fail("Unexpected CorElementType: " + dstCorElementType + ": Not a valid widening target."); dstObject = null; return(CreateChangeTypeException(srcEEType, dstEEType, semantics)); } Debug.Assert(dstObject.GetEETypePtr() == dstEEType); return(null); }