Ejemplo n.º 1
0
        // 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 (!((srcEEType.IsEnum || srcEEType.IsPrimitive) && (dstEEType.IsEnum || dstEEType.IsPrimitive || dstEEType.IsPointer)))
            {
                dstObject = null;
                return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
            }

            if (dstEEType.IsPointer)
            {
                dstObject = null;
                return(NotImplemented.ActiveIssue("TFS 457960 - Passing Pointers through Reflection Invoke"));
            }

            RuntimeImports.RhCorElementType dstCorElementType = dstEEType.CorElementType;
            if (!srcEEType.CorElementTypeInfo.CanWidenTo(dstCorElementType))
            {
                dstObject = null;
                return(CreateChangeTypeArgumentException(srcEEType, dstEEType));
            }

            switch (dstCorElementType)
            {
            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_BOOLEAN:
                dstObject = Convert.ToBoolean(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR:
                dstObject = Convert.ToChar(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I1:
                dstObject = Convert.ToSByte(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I2:
                dstObject = Convert.ToInt16(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I4:
                dstObject = Convert.ToInt32(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I8:
                dstObject = Convert.ToInt64(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U1:
                dstObject = Convert.ToByte(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U2:
                dstObject = Convert.ToUInt16(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U4:
                dstObject = Convert.ToUInt32(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U8:
                dstObject = Convert.ToUInt64(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R4:
                if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                {
                    dstObject = (float)(char)srcObject;
                }
                else
                {
                    dstObject = Convert.ToSingle(srcObject);
                }
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R8:
                if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                {
                    dstObject = (double)(char)srcObject;
                }
                else
                {
                    dstObject = Convert.ToDouble(srcObject);
                }
                break;

            default:
                Debug.Assert(false, "Unexpected CorElementType: " + dstCorElementType + ": Not a valid widening target.");
                dstObject = null;
                return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
            }

            if (dstEEType.IsEnum)
            {
                Type dstType = ReflectionCoreNonPortable.GetRuntimeTypeForEEType(dstEEType);
                dstObject = Enum.ToObject(dstType, dstObject);
            }

            Debug.Assert(dstObject.EETypePtr == dstEEType);
            return(null);
        }