views:

557

answers:

5

I imagine everyone has seen code like:

public void Server2ClientEnumConvert( ServerEnum server)
{
    switch(server)
    {
       case ServerEnum.One:
           return ClientEnum.ABC
       //And so on.

Instead of this badness we could do somthing like:

public enum ServerEnum
{
     [Enum2Enum(ClientEnum.ABC)]
     One,
}

Now we can use reflection to rip through ServerEnum and get the conversion mappings from the enum declaration itself.

The problem I am having here is in the declaration of the Enum2Enum attribute.

This works but replacing object o with Enum e does not. I do not want to be able to pass in objects to the constructor, only other enums.

public class EnumToEnumAttribute : Attribute
{
    public EnumToEnumAttribute(object o){}
}

This fails to compile.

public class EnumToEnumAttribute : Attribute
{
    public EnumToEnumAttribute(Enum e){}
}

Is there a reason for the compile error? How else could I pass in the information needed to map besides:

EnumtoEnumAttribute(Type dest, string enumString)

This seems too verbose but if it is the only way then I guess I will use it.

A: 

I would probably use struct as the type, and then throw an exception if it isn't an Enum type. I don't see how your (Type, string) option is any safer than using object or struct.

bdukes
A: 

Here are the rules for the types that can be included as Attribute parameters:

Daniel Jennings
A: 

@Danial Jennings I read through the rules there and found: "An enum type, provided it has public accessibility and the types in which it is nested (if any) also have public accessibility (Section 17.2).".

How does trying for Enum e in the constructor fail based on the quoted rule? Is it because being of type enum does not guarantee that the enums passed in are publicly visibly? This seems right. Is there a way for force this rule at compile time?

@ bdukes You are exactly correct. I should have thought about that more.

It looks like run time type checking is my only option to make sure I am only mapping enums to other enums.

kazakdogofspace
A: 

Why not use a Dictionary? This could be a static property of your class, initialized with those fancy schmancy object initializers we got in 3.0? You would not be typing more code (the mapping has to be done even with the Attribute sollution).

Daren Thomas
+3  A: 

Using almost the same example, you can achieve this directly in the enum:

public enum ServerEnum
{
   One = ClientEnum.ABC,
}

This has the benefit of not requiring Reflection, is easier to read (in my opinion), and overall requires less overhead.

Scott Dorman