Enums & Attributes (Looking for opinions)

Enums & Attributes (Looking for opinions)

Old forum URL: forums.lhotka.net/forums/t/1156.aspx


RangerGuy posted on Thursday, September 07, 2006

I am using some custom attributes to describe some of our system enums. They are basically used to inforce some validation rules. I read somewhere that it's not proper OOP to do this. That it's better to make a read only static collection/class structure and not use the enum and custom attributes. What's everybody think?

SonOfPirate replied on Friday, September 08, 2006

Enums are best used for fixed "values".  If your values have "behavior", which may be why you are attaching attributes, then the recommended practice is to use a structure or class (the former being more lightweight).

Unfortunately, the use of meta-data (which is what attributes provide) is a rather new concept to most OO programmers so it is not well-documented, discussed or even standardized how to handle them with respect to proper OOP practices.  The best approach is to simply look at what you are trying to accomplish with the attributes.  Are they simply "decorating" the value or are they providing functional information.

A good example is the System.SerializableAttribute.  This attribute, while appearing to provide behavior, really does nothing more that describe the class it is attached to.  The attribute doesn't provide functionality nor does it impose logic.  The serializer handles those aspects making use of the meta-data associated with the class to determine if it can be serialized or not.  The actual work and logic reside elsewhere.  Same applies to attributes like System.Xml.Serialization.XmlAttributeAttribute where you indicate to the serializer that the property should be treated like an attribute for the parent node and even possibly change the name of the attribute when it appears in XML.  These are all "decorative" things that don't affect how the entity behaves in and of itself.

If you'd like to provide an example of an enumeration you are using, I can certainly address the specifics of your case.  But, if you can apply the above litmus tests and say that your attributes are simply decoration, then you are fine.  I am struggling to think of an example where an attribute would be inappropriate.  I guess the best I can come up with would be an IsValidAttribute that you'd apply to enumeration values to indicate if the parent object should be invalidated when set to the specific value - and that's not a very good example.  In this case, the validity test should be in the object itself based on the value and not determined by an attribute.  But, my guess is that this is not reflective of what you are trying to accomplish.  So, please post an example if you could.

Hope that helps.

 

ajj3085 replied on Friday, September 08, 2006

I believe attributes enable what is more commonly being called Aspect Oriented Programming.

The idea is that many times in OO, you have code which isn't directly related to solving the problem at hand.  For example, serialization or security.  Instead of 'polluting' your class with this serialization code (which technically isn't the class' responsibility anyway), you mark it with the attribute.  Another class then is responsible for serializing ANY object. 

At least this is what my friend said when we were discussing Java (which he knows well) and .Net.  I trust his opinion though because he did take a few courses on AOP.

RangerGuy replied on Saturday, September 09, 2006

Thanks ajj3085 & SonOfPirate,

Maybe this will help more. We have some status that tell that define the status of an order like: Process,Payment Pending, Refunded etc.
We use the enum like so:
if(Order.Status == enumOrderStatus.Processed)
{
//Send Email
}
That works great and makes the code very readable. My problem is when setting the status. We have many more statuses and all statuses
are grouped in a category. The statuses are stored in a Database as well for reporting purposes. So we've made a standard
process if one needs to be added it's policy that it needs to be added in the code. The idea is we decide on the statuses
and they don't change except for a very rare case. So I figured I could use a custom attribute on the Enum Items to mark which category they belong to like so.

public enum enumOrderStatus
{
[StatusCategoryAttribute(1)]
Process = 1,
[StatusCategoryAttribute(2)]
Payment Pending = 2,
[StatusCategoryAttribute(2)]
Refunded =3
}
The order contains a StatusCategory child with contains statuses. With a simple IF statement I can check and make sure a status being

assigned to a category is valid for that category.

Hope that helps

Copyright (c) Marimer LLC