public void GetMethodByArgumentValuesResolvesToExactMatchIfAvailable()
        {
            var typedArg = new GetMethodByArgumentValuesTarget.DummyArgumentType[] {};
            var foo = new GetMethodByArgumentValuesTarget(1, typedArg);

            var type = typeof (GetMethodByArgumentValuesTarget);
            var candidateMethods = new MethodInfo[]
            {
                type.GetMethod("MethodWithSimilarArguments", new Type[] {typeof (int), typeof (ICollection)})
                ,
                type.GetMethod("MethodWithSimilarArguments",
                    new Type[] {typeof (int), typeof (GetMethodByArgumentValuesTarget.DummyArgumentType[])})
                , type.GetMethod("MethodWithSimilarArguments", new Type[] {typeof (int), typeof (object[])})
            };

            // ensure noone changed our test class
            Assert.IsNotNull(candidateMethods[0]);
            Assert.IsNotNull(candidateMethods[1]);
            Assert.IsNotNull(candidateMethods[2]);
            Assert.AreEqual("ParamArrayMatch", foo.MethodWithSimilarArguments(1, new object()));
            Assert.AreEqual("ExactMatch",
                foo.MethodWithSimilarArguments(1, (GetMethodByArgumentValuesTarget.DummyArgumentType[]) typedArg));
            Assert.AreEqual("AssignableMatch", foo.MethodWithSimilarArguments(1, (ICollection) typedArg));

            var resolvedMethod = ReflectionUtils.GetMethodByArgumentValues(candidateMethods, new object[] {1, typedArg});
            Assert.AreSame(candidateMethods[1], resolvedMethod);
        }
        public void GetMethodByArgumentValuesCanResolveWhenAmbiguousMatchIsOnlyDifferentiatedByParams()
        {
            var typedArg = new GetMethodByArgumentValuesTarget.DummyArgumentType[] {};
            var foo = new GetMethodByArgumentValuesTarget(1, typedArg);

            var type = typeof (GetMethodByArgumentValuesTarget);
            var candidateMethods = new MethodInfo[]
            {
                type.GetMethod("ParamOverloadedMethod", new Type[] {typeof (string), typeof (string), typeof (string)})
                , type.GetMethod("ParamOverloadedMethod", new Type[] {typeof (string), typeof (string), typeof (bool)})
                ,
                type.GetMethod("ParamOverloadedMethod",
                    new Type[] {typeof (string), typeof (string), typeof (string), typeof (string), typeof (object[])})
            };

            // ensure noone changed our test class
            Assert.IsNotNull(candidateMethods[0]);
            Assert.IsNotNull(candidateMethods[1]);
            Assert.IsNotNull(candidateMethods[2]);
            Assert.AreEqual("ThreeStringsOverload", foo.ParamOverloadedMethod(string.Empty, string.Empty, string.Empty));
            Assert.AreEqual("TwoStringsAndABoolOverload", foo.ParamOverloadedMethod(string.Empty, string.Empty, default(bool)));
            Assert.AreEqual("FourStringsAndAParamsCollectionOverload",
                foo.ParamOverloadedMethod(string.Empty, string.Empty, string.Empty, string.Empty, typedArg));

            var resolvedMethod = ReflectionUtils.GetMethodByArgumentValues(candidateMethods,
                new object[] {string.Empty, string.Empty, string.Empty, string.Empty, typedArg});
            Assert.AreSame(candidateMethods[2], resolvedMethod);
        }