internal static bool InternalCanDuckAs(
            Type type,
            Type toType,
            bool allowFuzzy,
            // ReSharper disable once UnusedParameter.Global
            // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Global
            bool throwIfNotAllowed
            )
        {
            if (ConverterLocator.HaveConverterFor(type, toType))
            {
                return(true);
            }

            var errors = GetDuckErrorsFor(type, toType, allowFuzzy);

            if (throwIfNotAllowed && errors.Any())
            {
                throw new UnDuckableException(errors);
            }
            return(!errors.Any());
        }
Пример #2
0
 private static bool MatchesTypeOrCanConvert(PropertyInfo needle, PropertyInfo matchByName)
 {
     return(matchByName.PropertyType == needle.PropertyType ||
            ConverterLocator.HaveConverterFor(matchByName.PropertyType, needle.PropertyType) ||
            EnumConverter.CanPerhapsConvertBetween(matchByName.PropertyType, needle.PropertyType));
 }
Пример #3
0
        // TODO: should be moved out into a shared location & used at duck-type
        // to prevent erroneous ducks
        private bool NonVoidFunctionAccepts(
            object value,
            object[] arguments,
            out Type[] parameterTypes,
            out Type returnType
            )
        {
            parameterTypes = null;
            returnType     = null;
            var funcType = value.GetType();

            if (!funcType.IsGenericType)
            {
                return(false);
            }

            var parameterCount = Array.IndexOf(FuncGenerics, funcType.GetGenericTypeDefinition());

            if (parameterCount != arguments.Length)
            {
                if (parameterCount > FuncGenerics.Length)
                {
                    throw new NotSupportedException(
                              $"methods with more than {FuncGenerics.Length} parameters are not supported");
                }

                return(false);
            }

            var genericParameters = funcType.GetGenericArguments();

            parameterTypes = genericParameters.Take(genericParameters.Length - 1).ToArray();
            returnType     = genericParameters.Last();
            var zipped = arguments.Zip(
                parameterTypes,
                (argument, parameterType) =>
                new
            {
                argumentType = argument?.GetType(),
                parameterType
            }
                );

            return(zipped.Aggregate(
                       true,
                       (acc, cur) =>
            {
                if (!acc)
                {
                    return false;
                }

                if (cur.argumentType is null &&
                    cur.parameterType.IsNullableType())
                {
                    return true;
                }

                if (cur.argumentType.IsAssignableOrUpCastableTo(cur.parameterType))
                {
                    return true;
                }

                return cur.argumentType == cur.parameterType ||
                ConverterLocator.HaveConverterFor(cur.argumentType, cur.parameterType);
            }));