2009-07-30 6 views
5

j'ai un dictionnaire qui est de type Dictionnaire [string, handler_func] où
handler_func est un délégué de typedélégué C# et attributs question syntaxe

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

maintenant j'ai une classe d'attributs comme si

[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; } 
    } 

} 

l'idée de base est que j'applique cet attribut à une méthode dans une classe et quelque part j'utiliser la réflexion pour remplir le Dictionnaire ci-dessus

problème

est moins que cette méthode est statique, le attribuiez ne fonctionne pas si

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

est à l'origine de la norme ont besoin d'une chose objet
Alors, quelles sont mes options (je ne veux pas la méthode de gestionnaire d'être statique Merci

Répondre

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

Je ne comprends pas pourquoi vous devez spécifier la méthode dans l'attribut: puisque l'attribut est appliqué à la méthode, vous pouvez déjà récupérer la méthode ... Vous pouvez faire quelque chose comme ça:

[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

Les paramètres d'attribut sont générés au moment de la compilation et stockés dans l'assembly, cela ne fonctionnera donc pas (HandleLoginResponse est une méthode non statique, donc liée à un objet, qui n'est disponible qu'au moment de l'exécution)

2

L'utilisation d'un délégué sur un attribut est ... inhabituelle et probablement non supportable. Une méthode d'instance nécessitera un objet, vous devrez donc inclure l'objet lors de la création du délégué (le paramètre target à Delegate.CreateDelegate via la réflexion), ou vous devrez utiliser un second type de délégué (sans cible sur le délégué, mais en prenant aussi la cible comme param0 - cela résoudra cela à la cible quand elle sera utilisée).

Cependant, je devine un peu ce que vous essayez de faire (il n'est pas 100% clair).

2

Un argument d'attribut doit être une expression constante, une expression typeof ou une expression de création de tableau d'un type de paramètre d'attribut.

2

Je serais très intéressé de voir un exemple de cela en travaillant avec une méthode statique, comme vous l'indiquez est possible dans la question!

problème

est moins que cette méthode est statique, le attribuiez ne fonctionne pas ...

par exemple supposons HandleLoginResponse est statique, que se passe-t-il alors?

Je ne pense pas que cela fera une différence. Vous ne pouvez pas créer de délégué const, vous ne pouvez donc pas passer un délégué à un attribut.

2

Earwicker: malheureusement, vous avez raison ... Il ne fonctionne pas non plus avec des méthodes statiques.Vous obtenez ce message d'erreur:

erreur CS0182: Un argument d'attribut doit être une expression constante, expression typeof ou un tableau d'expression création d'un paramètre d'attribut de type

Ce que je suis en train de faire est de spécifier une certaine méthode sera appelé quand une propriété est modifiée. Ce serait bon à faire en utilisant un délégué. Je l'ai eu travailler hier avec juste une chaîne, mais c'est un peu trop faible ... en utilisant une méthode statique serait mieux, mais cela semble être impossible avec la version actuelle du .NET Framework (3.5, VS2008).

Dommage!