Вызов метода базового класса игнорируя переопределенный метод в производном классе - C#
Формулировка задачи:
Как вызвать метод базового класса игнорируя переопределенный метод в производном классе.
PS переопределение метода в производном классе удалить нельзя, вшит в dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
public class Person
{
protected string ssn = "444-55-6666";
protected string name = "John L. Malgraine";
public virtual void GetInfo()
{
Console.WriteLine("Name: {0}", name);
Console.WriteLine("SSN: {0}", ssn);
}
}
class Employee : Person
{
public string id = "ABC567EFG";
public override void GetInfo()
{
// Calling the base class GetInfo method:
base.GetInfo();
Console.WriteLine("Employee ID: {0}", id);
}
}
class TestClass
{
static void Main()
{
Employee E = new Employee();
E.GetInfo();
Console.ReadKey();
}
}
}
изменить тело классов базового и производного нельзя.
Решение задачи: «Вызов метода базового класса игнорируя переопределенный метод в производном классе»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection.Emit;
namespace System.Reflection
{
public static class MethodInfoExtensions
{
public static object InvokeNotOverride(this MethodInfo MethodInfo, object Object, params object[] Arguments)
{ // void return, this parameter
var Parameters = MethodInfo.GetParameters();
if (Parameters.Length == 0)
{
if (Arguments != null && Arguments.Length != 0) throw new Exception("The number of arguments does not match the number of parameters");
}
else {
if (Parameters.Length != Arguments.Length) throw new Exception("The number of arguments does not match the number of parameters");
}
Type ReturnType = null;
if (MethodInfo.ReturnType != typeof(void))
{
ReturnType = MethodInfo.ReturnType;
}
var Type = Object.GetType();
var DynamicMethod = new DynamicMethod("", ReturnType, new Type[] { Type, typeof(Object) }, Type);
var ILGenerator = DynamicMethod.GetILGenerator();
ILGenerator.Emit(OpCodes.Ldarg_0); // this
for (var i = 0; i < Parameters.Length; i++)
{
var Parameter = Parameters[i];
ILGenerator.Emit(OpCodes.Ldarg_1); // load array argument
// get element at index
ILGenerator.Emit(OpCodes.Ldc_I4_S, i); // specify index
ILGenerator.Emit(OpCodes.Ldelem_Ref); // get element
var ParameterType = Parameter.ParameterType;
if (ParameterType.IsPrimitive)
{
ILGenerator.Emit(OpCodes.Unbox_Any, ParameterType);
}
else if (ParameterType == typeof(object))
{
// do nothing
}
else {
ILGenerator.Emit(OpCodes.Castclass, ParameterType);
}
}
ILGenerator.Emit(OpCodes.Call, MethodInfo);
var TestLabel = ILGenerator.DefineLabel();
ILGenerator.Emit(OpCodes.Ret);
return DynamicMethod.Invoke(null, new object[] { Object, Arguments });
}
}
class Program
{
class BaseClass
{
public virtual void Test()
{
Console.WriteLine("Test() from BaseClass");
}
}
class OverridingClass : BaseClass
{
public override void Test()
{
Console.WriteLine("Test() from OverridingClass");
}
}
public static void Main()
{
var d = new OverridingClass();
//typeof(BaseClass).GetMethod("Test").Invoke(d, null);
typeof(BaseClass).GetMethod("Test").InvokeNotOverride(d, null);
Console.ReadKey();
}
}
}