static void Main() { TestClass obj = new TestClass(); TestSubClass subObj = new TestSubClass(); OtherSubClass otherObj = new OtherSubClass(); obj.TestMethod(); subObj.TestMethod(); otherObj.TestMethod(); try { RedirectionHelper.RedirectCalls(typeof(TestSubClass).GetMethod("TestMethod"), typeof(DetourClass).GetMethod("TestMethod")); obj.TestMethod(); subObj.TestMethod(); otherObj.TestMethod(); } catch (Exception e) { Console.Out.WriteLine(e); } }
static void Main() { TestClass obj = new TestClass(); TestSubClass subObj = new TestSubClass(); OtherSubClass otherObj = new OtherSubClass(); obj.TestMethod(); subObj.TestMethod(); otherObj.TestMethod(); try { RedirectionHelper.RedirectCalls(typeof(TestSubClass).GetMethod("TestMethod"), typeof(DetourClass).GetMethod("TestMethod")); obj.TestMethod(); subObj.TestMethod(); otherObj.TestMethod(); } catch (Exception e) { Console.Out.WriteLine(e); } }
public void TestInvokeMemberMethod() { Type type = typeof(TestSubClass); BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod; BindingFlags bindingOptFlags = bindingFlags | BindingFlags.OptionalParamBinding; // 测试完整的调用。 Assert.AreEqual(TestSubClass.TestMethod(), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[0])); Assert.AreEqual(TestSubClass.TestMethod(10), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { 10 })); Assert.AreEqual(TestSubClass.TestMethod(10), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Explicit, null, new object[] { 10 })); Assert.AreEqual(TestSubClass.TestMethod(10, 20), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { 10, 20 })); Assert.AreEqual(TestSubClass.TestMethod(10, 20), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Explicit, null, new object[] { 10, 20 })); Assert.AreEqual(TestSubClass.TestMethod(30, null, true), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { 30, null, true })); // 测试完整的调用与类型转换。 Type[] invalidCastExceptions = { typeof(ArgumentException), typeof(InvalidCastException), typeof(MissingMethodException) }; Assert.AreEqual(TestSubClass.TestMethod(10), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { (short)10 })); Assert.AreEqual(TestSubClass.TestMethod(10), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Explicit, null, new object[] { (short)10 })); AssertExt.ThrowsException(() => type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { 10L }), invalidCastExceptions); Assert.AreEqual(TestSubClass.TestMethod(10), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Explicit, null, new object[] { 10L })); Assert.AreEqual(TestSubClass.TestMethod(10, 20), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { (short)10, (byte)20 })); AssertExt.ThrowsException(() => type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { 10UL, 20L }), invalidCastExceptions); AssertExt.ThrowsException(() => type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { 10, 20L }), invalidCastExceptions); Assert.AreEqual(TestSubClass.TestMethod(10, 20), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Explicit, null, new object[] { 10UL, 20L })); // 测试命名参数。 Assert.AreEqual(TestSubClass.TestMethod(30, "str", true), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { 30, "str", true })); Assert.AreEqual(TestSubClass.TestMethod(value2: "str", value1: 30, value3: true), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { "str", 30, true }, null, null, new[] { "value2", "value1", "value3" })); Assert.AreEqual(TestSubClass.TestMethod(30, "str", true), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { "str", 30, true }, null, null, new[] { "value2" })); Assert.AreEqual(TestSubClass.TestMethod(value3: true, value2: "str", value1: 30), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { true, "str", 30 }, null, null, new[] { "value3", "value2", "value1" })); Assert.AreEqual(TestSubClass.TestMethod(30, "str", true), type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { true, "str", 30 }, null, null, new[] { "value3", "value2" })); AssertExt.ThrowsException(() => type.InvokeMember("TestMethod", bindingFlags, PowerBinder.Default, null, new object[] { 10 }, null, null, new[] { "values" }), typeof(MissingMethodException)); // 测试默认参数和 params 参数。 Assert.AreEqual(TestSubClass.TestMethod2(30, "str", true, 1, 2, 3), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str", true, 1, 2, 3 })); Assert.AreEqual(TestSubClass.TestMethod2(30, "str", true), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str", true })); Assert.AreEqual(TestSubClass.TestMethod2(30, "str"), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str" })); Assert.AreEqual(TestSubClass.TestMethod2(30), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30 })); AssertExt.ThrowsException(() => type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[0]), typeof(MissingMethodException)); // 测试命名参数、默认参数和 params 参数。 Assert.AreEqual(TestSubClass.TestMethod2(value1: 30, value2: "str", value3: true, value4: new int[] { 1, 2, 3 }), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str", true, 1, 2, 3 }, null, null, new[] { "value1", "value2", "value3", "value4" })); Assert.AreEqual(TestSubClass.TestMethod2(30, "str", true, 1, 2, 3), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str", true, 1, 2, 3 }, null, null, new[] { "value1", "value2", "value3" })); Assert.AreEqual(TestSubClass.TestMethod2(value1: 30, value2: "str", value3: true), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str", true }, null, null, new[] { "value1", "value2", "value3" })); Assert.AreEqual(TestSubClass.TestMethod2(30, "str", true, 1, 2, 3), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str", 1, true, 2, 3 }, null, null, new[] { "value1", "value2", "value4" })); Assert.AreEqual(TestSubClass.TestMethod2(value1: 30, value2: "str", value4: new[] { 1 }), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str", new int[] { 1 } }, null, null, new[] { "value1", "value2", "value4" })); Assert.AreEqual(TestSubClass.TestMethod2(value4: new[] { 1 }, value3: true, value1: 30), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { new int[] { 1 }, true, 30 }, null, null, new[] { "value4", "value3", "value1" })); Assert.AreEqual(TestSubClass.TestMethod2(value4: new[] { 1 }, value1: 30), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { new int[] { 1 }, 30 }, null, null, new[] { "value4", "value1" })); Assert.AreEqual(TestSubClass.TestMethod2(value3: true, value1: 30), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { true, 30 }, null, null, new string[] { "value3", "value1" })); Assert.AreEqual(TestSubClass.TestMethod2(value1: 30), type.InvokeMember("TestMethod2", bindingOptFlags, PowerBinder.Default, null, new object[] { 30 }, null, null, new[] { "value1" })); // 测试泛型方法。 Assert.AreEqual(TestSubClass.TestMethod3(10, 20), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { 10, 20 })); Assert.AreEqual(TestSubClass.TestMethod3(10, 20), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { (short)10, 20 })); Assert.AreEqual(TestSubClass.TestMethod3((short)10, (short)20), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { (short)10, (short)20 })); Assert.AreEqual(TestSubClass.TestMethod3(10, (long)20), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { (short)10, (long)20 })); Assert.AreEqual(TestSubClass.TestMethod3(10, "str"), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { 10, "str" })); Assert.AreEqual(TestSubClass.TestMethod3(10, "str"), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { (short)10, "str" })); AssertExt.ThrowsException(() => type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { (long)10, "str" }), typeof(MissingMethodException)); Assert.AreEqual(TestSubClass.TestMethod3("text", "str"), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { "text", "str" })); AssertExt.ThrowsException(() => type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { "str", 10 }), typeof(MissingMethodException)); Assert.AreEqual(TestSubClass.TestMethod3("text", "str", 10), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { "text", "str", 10 })); Assert.AreEqual(TestSubClass.TestMethod3(10, 20, 30), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { 10, 20, 30 })); Assert.AreEqual(TestSubClass.TestMethod3(10, 20, "str"), type.InvokeMember("TestMethod3", bindingFlags, PowerBinder.Default, null, new object[] { 10, 20, "str" })); Assert.AreEqual("<System.Int32, System.String, System.Int32>(10, str, 20,30)", type.InvokeMember("TestMethod5", bindingOptFlags, PowerBinder.Default, null, new object[] { 10, "str", 20, 30 })); Assert.AreEqual("<System.Int32, System.String, System.Int64>(10, str, 20,30)", type.InvokeMember("TestMethod5", bindingOptFlags, PowerBinder.Default, null, new object[] { 10, "str", 20L, 30 })); Assert.AreEqual("<System.Int32, System.String, System.Int32>(10, test, 20,30)", type.InvokeMember("TestMethod5", bindingOptFlags, PowerBinder.Default, null, new object[] { 10, new int[] { 20, 30 }, "test" }, null, null, new string[] { "value1", "value3", "value2" })); // 测试选择方法。 BindingFlags bindingInsFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod; BindingFlags bindingInsOptFlags = bindingInsFlags | BindingFlags.OptionalParamBinding; TestSubClass subClass = new TestSubClass(); Assert.AreEqual(subClass.TestMethod4(10, 20), type.InvokeMember("TestMethod4", bindingInsFlags, PowerBinder.Explicit, subClass, new object[] { 10, 20 })); Assert.AreEqual(subClass.TestMethod4(true, "str"), type.InvokeMember("TestMethod4", bindingInsFlags, PowerBinder.Explicit, subClass, new object[] { true, "str" })); Assert.AreEqual(subClass.TestMethod4(10, "str"), type.InvokeMember("TestMethod4", bindingInsFlags, PowerBinder.Explicit, subClass, new object[] { 10, "str" })); Assert.AreEqual(subClass.TestMethod4(10, "str"), type.InvokeMember("TestMethod4", bindingInsOptFlags, PowerBinder.Explicit, subClass, new object[] { 10, "str" })); Assert.AreEqual(subClass.TestMethod4(10, "str", false), type.InvokeMember("TestMethod4", bindingInsFlags, PowerBinder.Explicit, subClass, new object[] { 10, "str", false })); Assert.AreEqual(subClass.TestMethod4(10, "str", 1), type.InvokeMember("TestMethod4", bindingInsFlags, PowerBinder.Explicit, subClass, new object[] { 10, "str", 1 })); Assert.AreEqual(subClass.TestMethod4(10, "str", new int[] { 1 }), type.InvokeMember("TestMethod4", bindingInsFlags, PowerBinder.Explicit, subClass, new object[] { 10, "str", new int[] { 1 } })); Assert.AreEqual(subClass.TestMethod4(10, "str", 1, 2), type.InvokeMember("TestMethod4", bindingInsFlags, PowerBinder.Explicit, subClass, new object[] { 10, "str", 1, 2 })); Assert.AreEqual(subClass.TestMethod4(true, true), type.InvokeMember("TestMethod4", bindingInsFlags, PowerBinder.Default, subClass, new object[] { true, true })); Assert.AreEqual(TestSubClass.TestMethod6(value2: 30, value1: "str"), type.InvokeMember("TestMethod6", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str" }, null, null, new string[] { "value2", "value1" })); Assert.AreEqual(TestSubClass.TestMethod6(value2: (short)30, value1: "str"), type.InvokeMember("TestMethod6", bindingOptFlags, PowerBinder.Default, null, new object[] { (short)30, "str" }, null, null, new string[] { "value2", "value1" })); Assert.AreEqual(TestSubClass.TestMethod6(value2: 30, value1: "str", value3: "str2"), type.InvokeMember("TestMethod6", bindingOptFlags, PowerBinder.Default, null, new object[] { 30, "str", "str2" }, null, null, new string[] { "value2", "value1" })); }