2009-07-30 11 views
5

tengo un diccionario que es de tipo Diccionario [cadena, handler_func] donde
handler_func es un delegado de tipoC# delegado y atributos pregunta sintaxis

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

ahora tengo una clase de atributo igual que

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

} 

la idea básica es aplico este atributo a un método en una clase y en algún lugar yo uso reflexión para llenar el Diccionario anterior

problema es menos que este método es estático del atrribuya no está funcionando por lo

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

está causando el estándar necesita una cosa objeto
¿Cuáles son mis opciones (no quiero el método de controlador sea estático) Gracias

Respuesta

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

No entiendo por qué tiene que especificar el método en el atributo: puesto que el atributo se aplica al método, ya se puede recuperar el método ... Se podría hacer algo así:

[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

Los parámetros de atributo se generan en tiempo de compilación y se almacenan en el ensamblado, así que esto no funcionará (HandleLoginResponse es un método no estático, por lo que está vinculado a un objeto, que solo está disponible en tiempo de ejecución)

2

Usar un delegado en un atributo es ... inusual, y probablemente no admitido.

Un método de instancia requerirá un objeto, por lo que deberá incluir el objeto al crear el delegado (el parámetro target en Delegate.CreateDelegate mediante reflexión), o tendrá que usar un segundo tipo de delegado (sin objetivo) en el delegado, pero adicionalmente tomando el objetivo como el param0 - resolverá esto al objetivo cuando se use).

Sin embargo, estoy adivinando un poco lo que intenta hacer (no está 100% claro).

2

Un argumento de atributo debe ser una expresión constante, tipo de expresión o expresión de creación de matriz de un tipo de parámetro de atributo.

2

¡Estaría muy interesado en ver un ejemplo de esto trabajando con un método estático, como implica que es posible en la pregunta!

problema es menos que este método es estático del atrribuya no está funcionando ...

por ejemplo, supongamos que HandleLoginResponse es estático, ¿qué ocurre entonces?

No creo que vaya a hacer ninguna diferencia. No puede hacer un delegado const, por lo que no puede pasar un delegado a un atributo.

2

Earwicker: desafortunadamente, tienes razón ... Tampoco funciona con métodos estáticos.Usted recibe este mensaje de error:

CS0182

de error: Un argumento atributo debe ser una expresión constante, typeof expresión o la creación de la matriz expresión de un tipo de parámetro atributo

Lo que estoy tratando de hacer es especificar un determinado método que se llamará cuando se cambie una propiedad. Esto sería bueno hacerlo con un delegado. Lo tuve funcionando ayer con solo una cadena, pero eso es un poco demasiado débil ... usar un método estático sería mejor, pero esto parece ser imposible con la versión actual de .NET Framework (3.5, VS2008).

¡Qué lástima!