Esempio n. 1
0
        //CONFORMING
        internal static MethodInfo GetUserDefinedCoercionMethod(Type convertFrom, Type convertToType, bool implicitOnly)
        {
            // check for implicit coercions first
            Type nnExprType = TypeUtils.GetNonNullableType(convertFrom);
            Type nnConvType = TypeUtils.GetNonNullableType(convertToType);

            // try exact match on types
            MethodInfo[] eMethods = nnExprType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            MethodInfo   method   = FindConversionOperator(eMethods, convertFrom, convertToType, implicitOnly);

            if (method != null)
            {
                return(method);
            }
            MethodInfo[] cMethods = nnConvType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            method = FindConversionOperator(cMethods, convertFrom, convertToType, implicitOnly);
            if (method != null)
            {
                return(method);
            }
            // try lifted conversion
            if (nnExprType != convertFrom || nnConvType != convertToType)
            {
                method = FindConversionOperator(eMethods, nnExprType, nnConvType, implicitOnly) ??
                         FindConversionOperator(cMethods, nnExprType, nnConvType, implicitOnly);
                if (method != null)
                {
                    return(method);
                }
            }
            return(null);
        }
Esempio n. 2
0
        private VarEnum GetComType(ref Type argumentType)
        {
            if (argumentType == typeof(Missing))
            {
                //actual variant type will be VT_ERROR | E_PARAMNOTFOUND
                return(VarEnum.VT_RECORD);
            }

            if (argumentType.IsArray)
            {
                //actual variant type will be VT_ARRAY | VT_<ELEMENT_TYPE>
                return(VarEnum.VT_ARRAY);
            }

            if (argumentType == typeof(UnknownWrapper))
            {
                return(VarEnum.VT_UNKNOWN);
            }
            else if (argumentType == typeof(DispatchWrapper))
            {
                return(VarEnum.VT_DISPATCH);
            }
            else if (argumentType == typeof(VariantWrapper))
            {
                return(VarEnum.VT_VARIANT);
            }
            else if (argumentType == typeof(BStrWrapper))
            {
                return(VarEnum.VT_BSTR);
            }
            else if (argumentType == typeof(ErrorWrapper))
            {
                return(VarEnum.VT_ERROR);
            }
            else if (argumentType == typeof(CurrencyWrapper))
            {
                return(VarEnum.VT_CY);
            }

            // Many languages require an explicit cast for an enum to be used as the underlying type.
            // However, we want to allow this conversion for COM without requiring an explicit cast
            // so that enums from interop assemblies can be used as arguments.
            if (argumentType.IsEnum)
            {
                argumentType = Enum.GetUnderlyingType(argumentType);
                return(GetComType(ref argumentType));
            }

            // COM cannot express valuetype nulls so we will convert to underlying type
            // it will throw if there is no value
            if (TypeUtils.IsNullableType(argumentType))
            {
                argumentType = TypeUtils.GetNonNullableType(argumentType);
                return(GetComType(ref argumentType));
            }

            //generic types cannot be exposed to COM so they do not implement COM interfaces.
            if (argumentType.IsGenericType)
            {
                return(VarEnum.VT_UNKNOWN);
            }

            VarEnum primitiveVarEnum;

            if (TryGetPrimitiveComType(argumentType, out primitiveVarEnum))
            {
                return(primitiveVarEnum);
            }

            // We could not find a way to marshal the type as a specific COM type
            return(VT_DEFAULT);
        }