C # делегат и атрибуты синтаксиса вопрос - PullRequest
5 голосов
/ 30 июля 2009

У меня есть словарь, который имеет тип Словарь [string, handler_func] где
handler_func является делегатом типа

public delegate void HANDLER_FUNC(object obj, TcpClient client);

теперь у меня есть класс атрибута, подобный

[AttributeUsage(AttributeTargets.Method)]
public class MessageHandlerAttribute : Attribute
{

    public MessageHandlerAttribute(string s1, HANDLER_FUNC hf)
    {
        s1 = name;
        msgtype = hf;
    }
    private string name;
    public string HandlerName
    {
        get { return name; }
        set { name = value; }
    }

    private HANDLER_FUNC msgtype;
    public HANDLER_FUNC MessageName
    {
        get { return msgtype; }
        set { msgtype = value; }
    }

}

Основная идея заключается в том, что я применяю этот атрибут к методу в классе и где-то использую отражение, чтобы заполнить словарь выше

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

[MessageHandlerAttribute("HandleLoginResponse",HandleLoginResponse)]
private void HandleLoginResponse(object obj, TcpClient client)  

вызывает потребность объекта в предмете
Итак, каковы мои варианты (я не хочу, чтобы метод обработчика был статическим) Спасибо

Ответы [ 6 ]

6 голосов
/ 30 июля 2009
[MessageHandlerAttribute("HandleLoginResponse",HandleLoginResponse)]
private void HandleLoginResponse(object obj, TcpClient client)

Я не понимаю, почему вам нужно указывать метод в атрибуте: поскольку атрибут применяется к методу, вы уже можете извлечь метод ... Вы можете сделать что-то подобное:

[MessageHandlerAttribute("HandleLoginResponse")]
private void HandleLoginResponse(object obj, TcpClient client)

...

foreach(MethodInfo method in this.GetType().GetMethods())
{
    MessageHandlerAttribute attr = Attribute.GetCustomAttribute(method, typeof(MessageHandlerAttribute)) as MessageHandlerAttribute;
    if (attr != null)
    {
        HANDLER_FUNC func = Delegate.CreateDelegate(typeof(HANDLER_FUNC), this, method) as HANDLER_FUNC;
        handlers.Add(attr.HandlerName, func);
    }
}
2 голосов
/ 16 февраля 2010

Earwicker: к сожалению, вы правы ... Он также не работает со статическими методами. Вы получаете это сообщение об ошибке:

ошибка CS0182: аргумент атрибута должен быть выражением константы, выражением typeof или выражением создания массива типа параметра атрибута

Я пытаюсь указать определенный метод, который будет вызываться при изменении свойства. Это было бы хорошо сделать с помощью делегата. У меня было вчера, когда он работал только со строкой, но это слишком слабое ... лучше использовать статический метод, но это кажется невозможным в текущей версии .NET Framework (3.5, VS2008)

Слишком плохо!

2 голосов
/ 30 июля 2009

Мне было бы очень интересно увидеть пример этой работы со статическим методом, как вы подразумеваете, возможно в вопросе!

Проблема в том, что если этот метод не является статическим, атрибут не работает ...

например. Предположим, что HandleLoginResponse является статическим, что происходит тогда?

Я не думаю, что это будет иметь значение. Вы не можете создать const делегат, поэтому вы не можете передать делегат атрибуту.

2 голосов
/ 30 июля 2009

Аргументом атрибута должно быть константное выражение, выражение typeof или выражение создания массива типа параметра атрибута.

2 голосов
/ 30 июля 2009

Использование делегата для атрибута ... необычно и, вероятно, не поддерживается.

Для метода экземпляра потребуется объект, поэтому вам нужно будет либо включить этот объект при создании делегата (параметр target для Delegate.CreateDelegate через отражение), либо вам потребуется использовать второй тип делегата ( без цели на делегате, но дополнительно принимающей цель в качестве param0 - это разрешит ее цели при использовании).

Однако, я немного догадываюсь о том, что вы пытаетесь сделать (это не на 100% ясно).

2 голосов
/ 30 июля 2009

Параметры атрибутов создаются во время компиляции и сохраняются в сборке, поэтому это не сработает (HandleLoginResponse - нестатический метод, поэтому он привязан к объекту, доступному только во время выполнения)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...