/// <summary> /// Retrieves an array of the values of the underlying type constants in a specified enumeration type. /// </summary> /// <remarks> /// This method can be used to get enumeration values when creating an array of the enumeration type is challenging. /// For example, <see cref="T:System.Reflection.MetadataLoadContext" /> or on a platform where runtime codegen is not available. /// </remarks> /// <returns>An array that contains the values of the underlying type constants in enumType.</returns> /// <exception cref="ArgumentException"> /// Thrown when the type is not Enum /// </exception> public override Array GetEnumValuesAsUnderlyingType() { if (!IsActualEnum) { throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); } // Get all of the values ulong[] values = Enum.InternalGetValues(this); switch (RuntimeTypeHandle.GetCorElementType(Enum.InternalGetUnderlyingType(this))) { case CorElementType.ELEMENT_TYPE_U1: { var ret = new byte[values.Length]; for (int i = 0; i < values.Length; i++) { ret[i] = (byte)values[i]; } return(ret); } case CorElementType.ELEMENT_TYPE_U2: { var ret = new ushort[values.Length]; for (int i = 0; i < values.Length; i++) { ret[i] = (ushort)values[i]; } return(ret); } case CorElementType.ELEMENT_TYPE_U4: { var ret = new uint[values.Length]; for (int i = 0; i < values.Length; i++) { ret[i] = (uint)values[i]; } return(ret); } case CorElementType.ELEMENT_TYPE_U8: { return((Array)values.Clone()); } case CorElementType.ELEMENT_TYPE_I1: { var ret = new sbyte[values.Length]; for (int i = 0; i < values.Length; i++) { ret[i] = (sbyte)values[i]; } return(ret); } case CorElementType.ELEMENT_TYPE_I2: { var ret = new short[values.Length]; for (int i = 0; i < values.Length; i++) { ret[i] = (short)values[i]; } return(ret); } case CorElementType.ELEMENT_TYPE_I4: { var ret = new int[values.Length]; for (int i = 0; i < values.Length; i++) { ret[i] = (int)values[i]; } return(ret); } case CorElementType.ELEMENT_TYPE_I8: { var ret = new long[values.Length]; for (int i = 0; i < values.Length; i++) { ret[i] = (long)values[i]; } return(ret); } default: throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType); } }
protected override TypeCode GetTypeCodeImpl() { TypeCode typeCode = Cache.TypeCode; if (typeCode != TypeCode.Empty) { return(typeCode); } CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this); switch (corElementType) { case CorElementType.ELEMENT_TYPE_BOOLEAN: typeCode = TypeCode.Boolean; break; case CorElementType.ELEMENT_TYPE_CHAR: typeCode = TypeCode.Char; break; case CorElementType.ELEMENT_TYPE_I1: typeCode = TypeCode.SByte; break; case CorElementType.ELEMENT_TYPE_U1: typeCode = TypeCode.Byte; break; case CorElementType.ELEMENT_TYPE_I2: typeCode = TypeCode.Int16; break; case CorElementType.ELEMENT_TYPE_U2: typeCode = TypeCode.UInt16; break; case CorElementType.ELEMENT_TYPE_I4: typeCode = TypeCode.Int32; break; case CorElementType.ELEMENT_TYPE_U4: typeCode = TypeCode.UInt32; break; case CorElementType.ELEMENT_TYPE_I8: typeCode = TypeCode.Int64; break; case CorElementType.ELEMENT_TYPE_U8: typeCode = TypeCode.UInt64; break; case CorElementType.ELEMENT_TYPE_R4: typeCode = TypeCode.Single; break; case CorElementType.ELEMENT_TYPE_R8: typeCode = TypeCode.Double; break; #if !CORECLR case CorElementType.ELEMENT_TYPE_STRING: typeCode = TypeCode.String; break; #endif case CorElementType.ELEMENT_TYPE_VALUETYPE: if (ReferenceEquals(this, typeof(decimal))) { typeCode = TypeCode.Decimal; } else if (ReferenceEquals(this, typeof(DateTime))) { typeCode = TypeCode.DateTime; } else if (IsActualEnum) { typeCode = GetTypeCode(Enum.InternalGetUnderlyingType(this)); } else { typeCode = TypeCode.Object; } break; default: #if CORECLR // GetSignatureCorElementType returns E_T_CLASS for E_T_STRING if (ReferenceEquals(this, typeof(string))) { typeCode = TypeCode.String; break; } #endif if (ReferenceEquals(this, typeof(DBNull))) { typeCode = TypeCode.DBNull; break; } typeCode = TypeCode.Object; break; } Cache.TypeCode = typeCode; return(typeCode); }
internal static bool IsPointer(RuntimeType type) { return(RuntimeTypeHandle.GetCorElementType(type) == CorElementType.Ptr); }
internal static bool IsSzArray(RuntimeType type) { return(RuntimeTypeHandle.GetCorElementType(type) == CorElementType.SzArray); }
protected override TypeCode GetTypeCodeImpl() { TypeCode typeCode = Cache.TypeCode; if (typeCode != TypeCode.Empty) { return(typeCode); } CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this); switch (corElementType) { case CorElementType.ELEMENT_TYPE_BOOLEAN: typeCode = TypeCode.Boolean; break; case CorElementType.ELEMENT_TYPE_CHAR: typeCode = TypeCode.Char; break; case CorElementType.ELEMENT_TYPE_I1: typeCode = TypeCode.SByte; break; case CorElementType.ELEMENT_TYPE_U1: typeCode = TypeCode.Byte; break; case CorElementType.ELEMENT_TYPE_I2: typeCode = TypeCode.Int16; break; case CorElementType.ELEMENT_TYPE_U2: typeCode = TypeCode.UInt16; break; case CorElementType.ELEMENT_TYPE_I4: typeCode = TypeCode.Int32; break; case CorElementType.ELEMENT_TYPE_U4: typeCode = TypeCode.UInt32; break; case CorElementType.ELEMENT_TYPE_I8: typeCode = TypeCode.Int64; break; case CorElementType.ELEMENT_TYPE_U8: typeCode = TypeCode.UInt64; break; case CorElementType.ELEMENT_TYPE_R4: typeCode = TypeCode.Single; break; case CorElementType.ELEMENT_TYPE_R8: typeCode = TypeCode.Double; break; case CorElementType.ELEMENT_TYPE_STRING: typeCode = TypeCode.String; break; case CorElementType.ELEMENT_TYPE_VALUETYPE: if (this == Convert.ConvertTypes[(int)TypeCode.Decimal]) { typeCode = TypeCode.Decimal; } else if (this == Convert.ConvertTypes[(int)TypeCode.DateTime]) { typeCode = TypeCode.DateTime; } else if (IsEnum) { typeCode = GetTypeCode(Enum.GetUnderlyingType(this)); } else { typeCode = TypeCode.Object; } break; default: if (this == Convert.ConvertTypes[(int)TypeCode.DBNull]) { typeCode = TypeCode.DBNull; } else if (this == Convert.ConvertTypes[(int)TypeCode.String]) { typeCode = TypeCode.String; } else { typeCode = TypeCode.Object; } break; } Cache.TypeCode = typeCode; return(typeCode); }
internal static bool IsByRef(RuntimeType type) { return(RuntimeTypeHandle.GetCorElementType(type) == CorElementType.ByRef); }
public static void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length) { if (sourceArray == null) { throw new ArgumentNullException(nameof(sourceArray)); } if (destinationArray == null) { throw new ArgumentNullException(nameof(destinationArray)); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "Value has to be >= 0."); } if (sourceArray.Rank != destinationArray.Rank) { throw new RankException(SR.Rank_MultiDimNotSupported); } if (sourceIndex < 0) { throw new ArgumentOutOfRangeException(nameof(sourceIndex), "Value has to be >= 0."); } if (destinationIndex < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex), "Value has to be >= 0."); } if (FastCopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length)) { return; } int source_pos = sourceIndex - sourceArray.GetLowerBound(0); int dest_pos = destinationIndex - destinationArray.GetLowerBound(0); if (dest_pos < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex), "Index was less than the array's lower bound in the first dimension."); } // re-ordered to avoid possible integer overflow if (source_pos > sourceArray.Length - length) { throw new ArgumentException(SR.Arg_LongerThanSrcArray, nameof(sourceArray)); } if (dest_pos > destinationArray.Length - length) { throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds", nameof(destinationArray)); } Type src_type = sourceArray.GetType().GetElementType(); Type dst_type = destinationArray.GetType().GetElementType(); var dst_type_vt = dst_type.IsValueType; // Need to check types even if nothing is copied if (length == 0) { var src_etype = RuntimeTypeHandle.GetCorElementType((RuntimeType)src_type); var dst_etype = RuntimeTypeHandle.GetCorElementType((RuntimeType)dst_type); // FIXME: More checks bool match = true; switch (dst_etype) { case CorElementType.ELEMENT_TYPE_OBJECT: case CorElementType.ELEMENT_TYPE_STRING: case CorElementType.ELEMENT_TYPE_CLASS: case CorElementType.ELEMENT_TYPE_ARRAY: case CorElementType.ELEMENT_TYPE_SZARRAY: if (src_type.IsPointer) { match = false; } break; case CorElementType.ELEMENT_TYPE_PTR: switch (src_etype) { case CorElementType.ELEMENT_TYPE_OBJECT: case CorElementType.ELEMENT_TYPE_STRING: case CorElementType.ELEMENT_TYPE_CLASS: case CorElementType.ELEMENT_TYPE_ARRAY: case CorElementType.ELEMENT_TYPE_SZARRAY: match = false; break; default: break; } break; default: break; } if (!match) { throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_CantAssignType); } } if (!Object.ReferenceEquals(sourceArray, destinationArray) || source_pos > dest_pos) { for (int i = 0; i < length; i++) { Object srcval = sourceArray.GetValueImpl(source_pos + i); if (srcval == null && dst_type_vt) { throw new InvalidCastException(); } try { destinationArray.SetValueImpl(srcval, dest_pos + i); } catch (ArgumentException) { throw CreateArrayTypeMismatchException(); } catch (InvalidCastException) { if (CanAssignArrayElement(src_type, dst_type)) { throw; } throw CreateArrayTypeMismatchException(); } } } else { for (int i = length - 1; i >= 0; i--) { Object srcval = sourceArray.GetValueImpl(source_pos + i); try { destinationArray.SetValueImpl(srcval, dest_pos + i); } catch (ArgumentException) { throw CreateArrayTypeMismatchException(); } catch { if (CanAssignArrayElement(src_type, dst_type)) { throw; } throw CreateArrayTypeMismatchException(); } } } }
internal static bool HasElementType(RuntimeType type) { CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(type); return(corElementType == CorElementType.Array || corElementType == CorElementType.SzArray || corElementType == CorElementType.Ptr || corElementType == CorElementType.ByRef); }
internal static bool IsArray(RuntimeType type) { CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(type); return(corElementType == CorElementType.Array || corElementType == CorElementType.SzArray); }
internal static bool IsPrimitive(RuntimeType type) { CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(type); return((corElementType >= CorElementType.Boolean && corElementType <= CorElementType.R8) || corElementType == CorElementType.I || corElementType == CorElementType.U); }
private static void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable) { if (sourceArray == null) { throw new ArgumentNullException(nameof(sourceArray)); } if (destinationArray == null) { throw new ArgumentNullException(nameof(destinationArray)); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "Value has to be >= 0."); } if (sourceArray.Rank != destinationArray.Rank) { throw new RankException(SR.Rank_MultiDimNotSupported); } if (sourceIndex < 0) { throw new ArgumentOutOfRangeException(nameof(sourceIndex), "Value has to be >= 0."); } if (destinationIndex < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex), "Value has to be >= 0."); } if (FastCopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length)) { return; } int source_pos = sourceIndex - sourceArray.GetLowerBound(0); int dest_pos = destinationIndex - destinationArray.GetLowerBound(0); if (dest_pos < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex), "Index was less than the array's lower bound in the first dimension."); } // re-ordered to avoid possible integer overflow if (source_pos > sourceArray.Length - length) { throw new ArgumentException(SR.Arg_LongerThanSrcArray, nameof(sourceArray)); } if (dest_pos > destinationArray.Length - length) { throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds", nameof(destinationArray)); } Type src_type = sourceArray.GetType().GetElementType(); Type dst_type = destinationArray.GetType().GetElementType(); var dst_type_vt = dst_type.IsValueType; if (src_type.IsEnum) { src_type = Enum.GetUnderlyingType(src_type); } if (dst_type.IsEnum) { dst_type = Enum.GetUnderlyingType(dst_type); } if (reliable) { var src_etype = RuntimeTypeHandle.GetCorElementType((RuntimeType)src_type); var dst_etype = RuntimeTypeHandle.GetCorElementType((RuntimeType)dst_type); if (src_etype != dst_etype) { throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_CantAssignType); } } // Need to check types even if nothing is copied if (length == 0) { if (!CanAssignArrayElement(src_type, dst_type)) { throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_CantAssignType); } return; } if (!Object.ReferenceEquals(sourceArray, destinationArray) || source_pos > dest_pos) { for (int i = 0; i < length; i++) { Object srcval = sourceArray.GetValueImpl(source_pos + i); if (srcval == null && dst_type_vt) { throw new InvalidCastException(); } try { destinationArray.SetValueImpl(srcval, dest_pos + i); } catch (ArgumentException) { throw CreateArrayTypeMismatchException(); } catch (InvalidCastException) { if (CanAssignArrayElement(src_type, dst_type)) { throw; } throw CreateArrayTypeMismatchException(); } } } else { for (int i = length - 1; i >= 0; i--) { Object srcval = sourceArray.GetValueImpl(source_pos + i); try { destinationArray.SetValueImpl(srcval, dest_pos + i); } catch (ArgumentException) { throw CreateArrayTypeMismatchException(); } catch { if (CanAssignArrayElement(src_type, dst_type)) { throw; } throw CreateArrayTypeMismatchException(); } } } }