tags:

views:

503

answers:

6

I have a dictionary which is of type Dictionary [string,handler_func] where
handler_func is a delegate of type

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

now I have an attribute class like so

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

}

The basic idea is I apply this attribute to a method in a class and somewhere I use reflection to fill up the Dictionary above

problem is unless this method is static the atrribute is not working so

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

is causing the standard need an object thing
So what are my options ( i do not want the handler method to be static ) Thanks

+2  A: 

Attribute parameters are generated at compile time and stored in the assembly, so this won't work (HandleLoginResponse is a non-static method, so it is bound to an object, which is only available at runtime)

Philippe Leybaert
+2  A: 

Using a delegate on an attribute is... unusual, and probably not supportable.

An instance method will require an object, so you will either need to include the object when creating the delegate (the target parameter to Delegate.CreateDelegate via reflection), or you'll need to use a second delegate type (with no target on the delegate, but additionally taking the target as the param0 - it'll resolve this to the target when used).

However, I'm guessing a bit at what you are trying to do (it isn't 100% clear).

Marc Gravell
+2  A: 

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.

adatapost
+3  A: 
[MessageHandlerAttribute("HandleLoginResponse",HandleLoginResponse)]
private void HandleLoginResponse(object obj, TcpClient client)

I don't understand why you need to specify the method in the attribute : since the attribute is applied to the method, you can already retrieve the method... You could do something like that :

[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);
    }
}
Thomas Levesque
cool this works , thanks
Rahul
+1  A: 

I'd be very interested to see an example of this working with a static method, as you imply is possible in the question!

problem is unless this method is static the atrribute is not working...

e.g. suppose HandleLoginResponse is a static, what happens then?

I don't think it will make any difference. You can't make a const delegate, so you can't pass a delegate to an attribute.

Daniel Earwicker
A: 

Earwicker: unfortunately, you're right... It doesn't work with static methods either. You get this error message:

error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

What I'm trying to do is specifying a certain method which will get called when a property is changed. This would be good to do using a delegate. I've had it working yesterday with just a string, but that's a bit too weak... using a static method would be better, but this seems to be impossible with the current version of the .NET Framework (3.5, VS2008).

Too bad!

Per Lundberg