Хранение объекта экземпляра метода с данным атрибутом, который будет вызван позже - PullRequest
0 голосов
/ 17 января 2020

Как видно из заголовка, используя отражение, я получаю методы того типа, которые имеют данный атрибут. Затем я хочу сохранить этот метод этого экземпляра объекта, чтобы я мог вызвать его позже. Я не уверен, как сохранить этот метод с этим экземпляром в словаре, который содержит действие. Сообщение является ключевым использованием в словаре. Все методы, имеющие этот атрибут, должны будут принимать 1 аргумент типа Dynami c.

static Dictionary<string, Action<dynamic>> networkHooks = new Dictionary<string, Action<dynamic>>();

private static void RegisterNetworkMethods(Type type, INetworkEnabled obj)
{
    // get the methods of this type that have the NetworkMethodAttribute
    var methods = (from m in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
                       where m.GetCustomAttributes(false).OfType<NetworkMethodAttribute>().Count() > 0
                       select m).ToList();

    foreach(var method in methods)
    {
        // get the NetworkMethodAttribute Message variable that was assigned
        var message = method.GetCustomAttribute<NetworkMethodAttribute>().Message;

        // todo: store this instance method in an Action somehow so it can be called later
        // networkHooks.Add(message, ???);
    }
}

Ответы [ 2 ]

2 голосов
/ 17 января 2020

Если вы используете Action<dynamic>, потому что методы могут принимать любые параметры, вы можете использовать эту версию, чтобы она работала. Затем можно вызвать DynamicInvoke(param) для делегатов, хранящихся в Словаре, для вызова методов

static Dictionary<string, Delegate> networkHooks = new Dictionary<string, Delegate>();

private static void RegisterNetworkMethods(Type type, object target)
{
    // get the methods of this type that have the NetworkMethodAttribute
    var methods = (from m in type.GetMethods(NonPublic | Instance)
                   where m.GetCustomAttributes(false).OfType<NetworkMethodAttribute>().Count() > 0
                   select m).ToList();

    foreach (var method in methods)
    {
        // get the NetworkMethodAttribute Message variable that was assigned
        var message = method.GetCustomAttribute<NetworkMethodAttribute>().Message;

        // todo: store this instance method in an Action somehow so it can be called later
        networkHooks.Add(message, Delegate.CreateDelegate(typeof(Action<Anything>).GetGenericTypeDefinition().MakeGenericType(method.GetParameters()[0].ParameterType), target, method.Name));
    }
}

Примечание: .OfType<NetworkMethodAttribute>().Count() > 0 можно изменить на .OfType<NetworkMethodAttribute>().Any(), это быстрее

1 голос
/ 17 января 2020

Нечто подобное должно двигать вас в правильном направлении.

    private static void RegisterNetworkMethods(Type type, INetworkEnabled obj)
    {
        // get the methods of this type that have the NetworkMethodAttribute
        var methods = (from m in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
                       where m.GetCustomAttributes(false).OfType<NetworkMethodAttribute>().Count() > 0
                       select m).ToList();

        foreach(var method in methods)
        {
            // get the NetworkMethodAttribute Message variable that was assigned
            var message = method.GetCustomAttribute<NetworkMethodAttribute>().Message;

            var action = (Action<dynamic>) Delegate.CreateDelegate(typeof(Action<dynamic>), method);

            networkHooks.Add(message, action);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...