Exemplo n.º 1
0
        private AphidInteropMethodArg(
            ParameterInfo parameter,
            object argument,
            bool?constructsParamArray = null)
        {
            Argument = argument;

            if (argument != null)
            {
                ArgumentType = argument.GetType();

                lock (ParamCache)
                {
                    if (!ParamCache.TryGetValue(parameter, out _paramInfo))
                    {
                        ParamCache.Add(
                            parameter,
                            _paramInfo = new ParameterInfoCache(parameter, ArgumentType));

                        _argInfo = _paramInfo.InitialArgumentTypeCache;
                    }
                    else if (!_paramInfo.ArgumentTypeCache.TryGetValue(ArgumentType, out _argInfo))
                    {
                        _paramInfo.ArgumentTypeCache.Add(
                            ArgumentType,
                            _argInfo = new ArgumentTypeCache(
                                ArgumentType,
                                _paramInfo,
                                _paramInfo.TargetType));
                    }
                }
            }
            else
            {
                lock (ParamCache)
                {
                    if (!ParamCache.TryGetValue(parameter, out _paramInfo))
                    {
                        ParamCache.Add(
                            parameter,
                            _paramInfo = new ParameterInfoCache(parameter));
                    }

                    _argInfo = new ArgumentTypeCache();
                }
            }

            IsGeneric = TargetType.IsGenericType;

            if (_argInfo.NeedsStringToCharCheck)
            {
                if (((string)Argument).Length == 1)
                {
                    IsExactBasicTypeMatch = true;
                }

                //IsExactUserReferenceTypeMatch = false;
            }
            else if (_argInfo.NeedsDecimalFitCheck)
            {
                IsConvertibleNumberPair = AphidTypeConverter.CanConvertDecimal(
                    (decimal)Argument,
                    TargetType);
            }
            else
            {
                IsConvertibleNumberPair       = _argInfo.IsConvertibleNumberPair;
                IsExactBasicTypeMatch         = _argInfo.IsExactBasicTypeMatch;
                IsExactUserReferenceTypeMatch = _argInfo.IsExactUserReferenceTypeMatch;
            }

            if (HasParamArray)
            {
                if (constructsParamArray == null)
                {
                    if (!HasParamArray)
                    {
                        ConstructsParamArray = false;
                        PassesParamArray     = false;
                    }
                    else
                    {
                        if (!IsExactTypeMatch &&
                            ArgumentType?.GetInterface("IEnumerable") != null)
                        {
                            ConstructsParamArray = true;
                            PassesParamArray     = false;
                        }
                        else
                        {
                            ConstructsParamArray = false;
                            PassesParamArray     = true;
                        }
                    }
                }
                else
                {
                    ConstructsParamArray = constructsParamArray.Value;
                    PassesParamArray     = !ConstructsParamArray;
                }
            }
        }
Exemplo n.º 2
0
        public ArgumentTypeCache(
            Type argumentType,
            ParameterInfoCache targetParam,
            Type targetType)
        {
            if (IsExactTypeMatch = argumentType == targetType)
            {
                IsExactBasicTypeMatch =
                    argumentType.IsPrimitive ||
                    argumentType.IsEnum ||
                    argumentType == typeof(string) ||
                    argumentType == typeof(decimal);

                IsExactUserReferenceTypeMatch = argumentType.IsClass && argumentType != typeof(object);
                HasToStringConversion         = targetType == typeof(string);
            }
            else if (argumentType == typeof(string) && targetType == typeof(char[]))
            {
                IsExactBasicTypeMatch         = false;
                IsExactUserReferenceTypeMatch = false;
                HasToStringConversion         = targetType == typeof(string);
            }
            else if (argumentType == typeof(char) && targetType == typeof(string))
            {
                IsExactBasicTypeMatch         = true;
                IsExactUserReferenceTypeMatch = false;
                HasToStringConversion         = targetType == typeof(string);
            }
            else if (argumentType != typeof(string) || targetType != typeof(char))
            {
                if ((ImplicitConversionOperator = ConversionOperator.GetImplicitOperator(
                         targetType,
                         argumentType)) != null)
                {
                    HasImplicitConversion = true;
                }
                else if ((ExplicitConversionOperator = ConversionOperator.GetExplicitOperator(
                              targetType,
                              argumentType)) != null)
                {
                    HasExplicitConversion = true;
                }

                if (targetType == typeof(string))
                {
                    HasToStringConversion = true;
                }

                IsExactBasicTypeMatch = IsExactUserReferenceTypeMatch = false;
            }
            else
            {
                HasToStringConversion  = targetType == typeof(string);
                NeedsStringToCharCheck = true;
            }

            IsDerivedFromUserReferenceType =
                targetParam.IsClass &&
                targetType != typeof(object) &&
                targetType != typeof(object[]) &&
                (argumentType == null ||
                 (argumentType.IsClass &&
                  argumentType.IsDerivedFrom(targetType)));

            IsNonRootImplementationOfTarget =
                targetType.IsInterface &&
                argumentType != null &&
                argumentType != typeof(object) &&
                argumentType.GetInterfaces().Contains(targetType);

            if (argumentType == typeof(decimal) && AphidTypeConverter.IsNumber(targetType))
            {
                NeedsDecimalFitCheck = true;
                IsPrecisionLost      = targetType == typeof(float) || targetType == typeof(double);
            }
            else if (targetType == typeof(decimal) && AphidTypeConverter.IsNumber(argumentType))
            {
                IsConvertibleNumberPair = true;
            }
            else
            {
                // Todo: cover non-decimal to non-decimal checks e.g.
                // ulong to uint -> uint.MinValue <= ulongValue && ulongValue <= uint.MaxValue
                IsConvertibleNumberPair = false;
            }
        }