Kii*_*Kii 18 .net c# reflection
如何使用反射调用被派生类重写的基本方法?
class Base
{
public virtual void Foo() { Console.WriteLine("Base"); }
}
class Derived : Base
{
public override void Foo() { Console.WriteLine("Derived"); }
}
public static void Main()
{
Derived d = new Derived();
typeof(Base).GetMethod("Foo").Invoke(d, null);
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
此代码始终显示"派生"...
Dog*_*ett 33
尽管当前的答案已被接受,但实际上可以通过使用这样的动态方法来更改原始类:
static void Main(string[] args)
{
Derived foo = new Derived();
foo.Foo();
MethodInfo method = typeof(Base).GetMethod("Foo");
DynamicMethod dm = new DynamicMethod("BaseFoo", null, new Type[] { typeof(Derived) }, typeof(Derived));
ILGenerator gen = dm.GetILGenerator();
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, method);
gen.Emit(OpCodes.Ret);
var BaseFoo = (Action<Derived>)dm.CreateDelegate(typeof(Action<Derived>));
BaseFoo(foo);
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
你可以看到它仍然相对简单
Kii*_*Kii 33
经过很长一段时间,我终于找到了比DynamicMethod更好的解决方案:
class CallOverride
{
public static void Test()
{
var obj = new Override();
var method = typeof(object).GetMethod("ToString");
var ftn = method.MethodHandle.GetFunctionPointer();
var func = (Func<string>)Activator.CreateInstance(typeof(Func<string>), obj, ftn);
Console.WriteLine(func());
}
}
class Override
{
public override string ToString()
{
return "Nope";
}
}
Run Code Online (Sandbox Code Playgroud)
此解决方案使用委托的标准构造函数签名:
public Delegate(object target, IntPtr ftn)
Run Code Online (Sandbox Code Playgroud)
其中target是目标实例,ftn是函数指针.它使用base方法的函数指针直接调用它,因此委托将指向实际的基本方法,而不是重写的方法.
即使经过反思,你也无法做到这一点。C# 中的多态性实际上保证了始终会被调用,即使在强制转换回其基类Derived.Foo()
的实例上也是如此。Derived
Base.Foo()
从实例调用的唯一方法Derived
是显式地使其可从Derived
类访问:
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("Derived");
}
public void BaseFoo()
{
base.Foo();
}
}
Run Code Online (Sandbox Code Playgroud)