Как я могу передать метод, полученный отражением в C #, методу, который принимает метод в качестве делегата? - PullRequest
6 голосов
/ 26 октября 2009

Я понимаю, что название должно быть прочитано более одного раза для понимания ...:)

Я реализовал пользовательский атрибут, который применяю к методам в моих классах. Все методы, которые я применяю для атрибута, имеют одинаковую подпись, и поэтому я определил делегата для них:

public delegate void TestMethod();

У меня есть структура, которая принимает этот делегат в качестве параметра

struct TestMetaData
{
  TestMethod method;
  string testName;
}

Можно ли из отражения получить метод с пользовательским атрибутом и передать его в структуру в член 'method'?

Я знаю, что вы можете вызвать его, но я думаю, что рефлексия не даст мне фактический метод из моего класса, который я могу привести к делегату TestMethod.

Ответы [ 4 ]

11 голосов
/ 26 октября 2009

Получив MethodInfo через Reflection, вы можете использовать Delegate.CreateDelegate , чтобы превратить его в Делегат, а затем использовать Reflection, чтобы установить его непосредственно в свойстве / поле вашей структуры.

1 голос
/ 26 октября 2009

Вы можете создать делегата, который вызывает ваш отраженный метод во время выполнения, используя Invoke или Delegate.CreateDelegate.

Пример:

using System;
class Program
{
    public delegate void TestMethod();
    public class Test
    {
        public void MyMethod()
        {
            Console.WriteLine("Test");
        }
    }
    static void Main(string[] args)
    {
        Test t = new Test();
        Type test = t.GetType();
        var reflectedMethod = test.GetMethod("MyMethod");
        TestMethod method = (TestMethod)Delegate.CreateDelegate(typeof(TestMethod), t, reflectedMethod);
        method();
    }
}
0 голосов
/ 26 октября 2009

Как пример:

using System;
using System.Linq;

using System.Reflection;
public delegate void TestMethod();
class FooAttribute : Attribute { }
static class Program
{
    static void Main() {
        // find by attribute
        MethodInfo method =
            (from m in typeof(Program).GetMethods()
             where Attribute.IsDefined(m, typeof(FooAttribute))
             select m).First();

        TestMethod del = (TestMethod)Delegate.CreateDelegate(
            typeof(TestMethod), method);
        TestMetaData tmd = new TestMetaData(del, method.Name);
        tmd.Bar();
    }
    [Foo]
    public static void TestImpl() {
        Console.WriteLine("hi");
    }
}

struct TestMetaData
{
    public TestMetaData(TestMethod method, string name)
    {
        this.method = method;
        this.testName = name;
    }
    readonly TestMethod method;
    readonly string testName;
    public void Bar() { method(); }
}
0 голосов
/ 26 октября 2009

Также вам нужен подходящий делегат, который уже объявлен

...