Skip to content

Instantly share code, notes, and snippets.

@pardeike
Created June 7, 2020 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pardeike/9362bfa950862ebf48b25ca7c72e39d5 to your computer and use it in GitHub Desktop.
Save pardeike/9362bfa950862ebf48b25ca7c72e39d5 to your computer and use it in GitHub Desktop.
// use in LINQPad
delegate string Test1Delegate(int n, ref float f);
void Main()
{
var bar = new Bar();
var baseTest1 = (Test1Delegate)GetBaseMethod(typeof(Foo).GetMethod("Test1"), bar);
var f = 789f;
var res2 = baseTest1(456, ref f);
Console.WriteLine(res2);
var baseTest2 = (Action<int, float>)GetBaseMethod(typeof(Foo).GetMethod("Test2"), bar);
baseTest2(1456, 1789f);
}
static Delegate GetBaseMethod(MethodInfo method, object instance)
{
var ptr = method.MethodHandle.GetFunctionPointer();
var pTypes = method.GetParameters().Select(p => p.ParameterType).ToList();
if (method.ReturnType == typeof(void))
{
var aType = Type.GetType($"System.Action`{pTypes.Count}", true, false);
var actionType = aType.MakeGenericType(pTypes.ToArray());
return (Delegate)Activator.CreateInstance(actionType, instance, ptr);
}
pTypes.Add(method.ReturnType);
var fType = Type.GetType($"System.Func`{pTypes.Count}", true, false);
var functionType = fType.MakeGenericType(pTypes.ToArray());
return (Delegate)Activator.CreateInstance(functionType, instance, ptr);
}
public class Foo
{
public virtual string Test1(int n, ref float f)
{
Console.WriteLine($"base test {n}");
return "base result";
}
public virtual void Test2(int n, float f)
{
Console.WriteLine($"base test {n}");
}
}
public class Bar : Foo
{
public override string Test1(int n, ref float f)
{
Console.WriteLine($"sub test {n}");
return "sub result";
}
public override void Test2(int n, float f)
{
Console.WriteLine($"sub test {n}");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment