C# Reflection return method content as Delegate

Multi tool use


C# Reflection return method content as Delegate
I would like to call functions using Reflection
I want to make the following section static:
var mi = Abilities.instance.GetType ().GetMethod (abilities[i].name, BindingFlags.Instance | BindingFlags.NonPublic) as MethodInfo;
AbilityAction code = (AbilityAction)Delegate.CreateDelegate(typeof(AbilityAction), this, mi);
And then call it:
AbilityAction code = GetMethodInClass(abilities[i].name /*e.g. MegaJump*/, Abilities, AbilityAction);
I have tried my best but it gives me alot of errors:
public static Delegate GetMethodInClass<T, D>(string methodName, T sourceClass, D delegateType) where D : Delegate {
var mi = sourceClass.GetType().GetMethod (methodName, BindingFlags.Instance | BindingFlags.NonPublic) as MethodInfo;
return (D)Delegate.CreateDelegate(typeof(delegateType), this, mi);
}
Thanks in advance.
dynamic
"I have tried my best but it gives me alot of errors" - what errors did it give you, exactly? and were they at runtime, or at compile-time?
– Marc Gravell♦
38 mins ago
what method are you trying to create a delegate to? does it match the delegate signature? (plus or minus the target /
this
part, which can be fudged); can we see how AbilityCode
is defined, and a method you're trying to target?– Marc Gravell♦
36 mins ago
this
AbilityCode
finally; is it possible that the only "error" here is passing
this
instead of sourceClass
as the target instnace? (note: there are a few things that could be prettier, but aren't actually errors)– Marc Gravell♦
35 mins ago
this
sourceClass
It is giving me these errors: at return line: Keyword
this' is not valid in a static property, static method, or static field initializer and Cannot convert type
System.Delegate' to `D'– Mc Midas
13 mins ago
this' is not valid in a static property, static method, or static field initializer and Cannot convert type
1 Answer
1
I can't see what you're actually trying to do without the delegate type and example method, but ... reading between the lines as best as I can, here's a similar example that works:
using System;
using System.Reflection;
class Foo
{
public int Bar(string whatever) => whatever.Length;
}
delegate int AbilityAction(string name);
static class Program
{
static void Main(string args)
{
var foo = new Foo();
var action = GetMethodInClass<AbilityAction>(nameof(foo.Bar), foo);
int x = action("abc");
Console.WriteLine(x); // 3
}
public static D GetMethodInClass<D>(string methodName, object target) where D : Delegate
{
var mi = target.GetType().GetMethod(methodName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
return (D)Delegate.CreateDelegate(typeof(D), target, mi);
}
}
Note: if you don't have C# 7.3, the method needs some minor tweaks:
public static D GetMethodInClass<D>(string methodName, object target) where D : class
{
var mi = target.GetType().GetMethod(methodName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
return (D)(object)Delegate.CreateDelegate(typeof(D), target, mi);
}
Thanks for your solution, but the compiler wont take the D as a Delegate: error CS0702: A constraint cannot be special class `System.Delegate'
– Mc Midas
9 mins ago
@McMidas that requires C# 7.3; if you don't have C# 7.3, just remove the constraint - it won't enforce it, but: it'll work;
where T : class
may be a reasonable compromise– Marc Gravell♦
7 mins ago
where T : class
@McMidas oh, and the last line needs an indirection to make the compiler happy:
return (D)(object)Delegate.CreateDelegate(typeof(D), target, mi);
- note the addition of (object)
- this basically defers the type-check to the runtime, where-as C# 7.3 (with the T : Delegate
constraint) is able to confirm it at compile-time– Marc Gravell♦
5 mins ago
return (D)(object)Delegate.CreateDelegate(typeof(D), target, mi);
(object)
T : Delegate
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
This sort of code is pretty grody. Consider if you're not better off using something like
dynamic
, or passing expression trees rather than strings.– Jeroen Mostert
46 mins ago