Solved

Passing Delegate into Attribute constructor

Posted on 2004-10-10
6
518 Views
Last Modified: 2013-11-19
I want to do something like the following:

public delegate void EmptyDelegate();

public class MyAttAttribute : Attribute
{
public MyAttAttribute(EmptyDelegate Del)
{
...
}
}

[MyAtt(new EmptyDelegate(Foo.DoNothing))]
public class Foo
{
public static void DoNothing()
{
...
}
}

However, when I compile, I'm told that Attribute constructors must take only constants.  Is there anyway to pass a Delegate into an Attribute constructor?

In the meantime, my workaround has been to add the following MyAttAttribute constructor:

public MyAttAttribute(Type ClassType, string DelegateName) : this((EmptyDelegate)EmptyDelegate.CreateDelegate(typeof(EmptyDelegate), ClassType, DelegateName)) { }

However, this is incredibly lame.
0
Comment
Question by:a_goat
  • 3
  • 3
6 Comments
 
LVL 6

Accepted Solution

by:
etmendz earned 250 total points
ID: 12275117
An incredibly lame approach that simply works. I think calls to attributes are resolved at compile-time which explains why you need to pass constants. However, the instance of the attribute is defined at run-time which you may access using Attribute.GetCustomAttributes() and/or reflections.

Try to work around this limitation rather than against it. Attributes are not meant to be very dynamic. As the name implies, Attributes are meant to be declarative, definitive and informative rather than intentionally functional. Most of the time, you'll use attributes to trigger external functionalities instead.

The amount of information you expose through attributes enables services to be invented that consume these information...

Have fun.
0
 
LVL 3

Author Comment

by:a_goat
ID: 12275540
The basic idea of what I'm trying to do is build an engine that processes incoming byte[]s from a socket.  I get a 4 byte header consisting of MessageType and Size.  From the MessageType, I can determine what kind of object this is.  I don't want to have a central factory though.  So the idea I had was that each class has attributes which track what MessageTypes it can handle, and a delegate for each.  That way I can maintain a list of MessageTypes and the accompanying delegate and easily create objects.

Kinda like a modular factory model, where you just need to put a new piece of equipment on the floor and it starts churning stuff out.
0
 
LVL 3

Author Comment

by:a_goat
ID: 12275550
As an aside, is there a way in the attribute's code to discover what class it is associated with (assuming it is associated with a class).

That actually brings up a good idea.  I could potentially put these attributes on methods instead of the class.  It would mean more crawling though.  Ugh
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 6

Expert Comment

by:etmendz
ID: 12283587
Interesting... let me see...

* Dynamic *
Add attributes to your classes in order to define their purpose passing only types and strings and stuffs as you are doing now. Keep the constructor simple storing the passed parameters as properties of the attribute instance at run-time.

Then create a separate class which uses reflections to get information about your classes and their attributes and then store the inventory to a collection or XML. The structure should map classes or methods against message types and delegates for example. Use this inventory to instantiate objects.

* Static *
Maintain the inventory of classes, methods mapped to message types and delegates in an XML or configuration file and let a separate class load them at run-time. No need for attributes but should work the same.

See which one would work best for you. I think the * Static * would load and initialize faster, though... Here's a tip, read about attributes used for AOP and instrumentation in .Net. You might find something useful...

http://msdn.microsoft.com/msdnmag/issues/02/03/aop/
http://msdn.microsoft.com/msdnmag/issues/04/04/InstrumentationinNET/default.aspx
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=572
http://www.dotnetguru.org/us/modules.php?op=modload&name=News&file=index&catid=&topic=16
You can also search in Google for "AOP in .Net" or "Instrumentation in .Net" for more information...

Have fun.
0
 
LVL 3

Author Comment

by:a_goat
ID: 12286049
So what I've got now is the dynamic version, which is what I want.  Static has too much danger of some noob coming in and jacking it all up (always a concern at my job).  

There are 2 flaws with what I'm doing though:

1.) The developer has to be careful to put the correct type in the attribute's constructor.  i.e.

[MyAtt(typeof(Foo), "DoNothing")]
public class Foo
{
public static void DoNothing()
{
...
}
}

Because the class is unnecessarily copied, that can lead to problems

2.) The developer can deliberately put the wrong type in the constructor.  This just leads to some of the worst spagetti code imaginable.  i.e.

[MyAtt(typeof(Bar), "DoNothingBar")]
public class Foo
{
public static void DoNothingFoo()
{
...
}
}

[MyAtt(typeof(Foo), "DoNothingFoo")]
public class Bar
{
public static void DoNothingBar()
{
...
}
}

Here Bar and Foo's attributes are cross-matched.  

Both these problems would be solved if the attribute knew what class it was associated with.  Is there any way to discover that?
0
 
LVL 6

Expert Comment

by:etmendz
ID: 12294402
Looks like it is not possible... Use reflections to collect the inventory of members... You can use attributes to identify which members to include in your inventory... Then use another class to map the inventory to your collection of rules...

Have fun...
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

JavaScript has plenty of pieces of code people often just copy/paste from somewhere but never quite fully understand. Self-Executing functions are just one good example that I'll try to demystify here.
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now