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

            Type type = typeof(GetMethodByArgumentValuesTarget);
            MethodInfo[] 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));

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

            Type type = typeof(GetMethodByArgumentValuesTarget);
            MethodInfo[] 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 no one 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));

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