tags:

views:

509

answers:

6

(OK, I'll expose the depths of my ignorance here, please be gentle)

Background

I've got a method which looks (a bit) like this:

public void AddLink(Enum enumVal)
{
     string identifier = m_EnumInterpreter(enumVal);
     AddLink(identifier);
}

The EnumInterpreter is a Func<Enum, string> that is passed in when the parent class is created.

I'm using Enum because at this level it is 'none of my business'- I don't care which specific enum it is. The calling code just uses a (generated) enum to avoid magic strings.

Question

If the EnumInterpreter sends back an empty string, I'd like to throw an exception with the actual value of enumVal. I thought I would just be able to cast to int, but it the compiler won't have it. What am I doing wrong? (Please don't say 'everything').

+2  A: 

No, you aren't able to cast it to an int because System.Enum is not an enum, it's just the base class for enums.

EDIT:

You can get the value as follows, but it is ugly:

int intVar = (int)enuYourEnum.GetType().GetField("value__").GetValue(objYourEnum);
Maximilian Mayerl
Yup, that's ugly.
Benjol
Note that this will fail if `int` is *not* the underlying type of the enum.
P Daddy
Well, I must confess that it isn't, it's a uint, but I think I've found something that works for me...
Benjol
+5  A: 

System.Enum cannot be directly cast to Integer, but it does explicitly implement IConvertible, meaning you can use the following:

public void AddLink(Enum enumVal)
{
    string identifier = m_EnumInterpreter(Convert.ToInt32(enumVal));
    AddLink(identifier);
}

Keep in mind that if your Enum is actually using something other than an Integer (such as a float), you'll lose the non-integer data on conversion. Or obviously replace the Convert call with whatever you are converting from (if it's known)

Ryan Brunner
C# enums cannot be floats: http://msdn.microsoft.com/en-us/library/sbbt4032%28VS.71%29.aspx - **Every enumeration type has an underlying type, which can be any integral type**
Igor Zevaka
+1  A: 

Various things here:

1) the answer of Ryan looks ok, but... I would rather pass the Enum down to the enum interpreter, so that you can do the whole Convert.To... there. If you know that you are using ONLY integer based enums, the Convert.ToInt32() is just fine. Otherwise you may want to add by using either reflection or try/catch other conversions.

2) You may also consider using members of the Enum class, like .GetName(), .GetValue(), etc. since they deal directly with the defined names and values independent of the enum type.

3) technically I would not throw the exception outside the enum interpreter. If that condition is generally true, throw the exception from inside the enum interpreter, so that all uses of the class will benefit of the validation. Or you might end up duplicating code.

4) you seem to have an C++/MFC background judging from your variable naming. You might want to get into C# style naming conventions, it will ease your life when using/reading other peoples code and libraries. Check out MS's StyleCop for a good addin to help with naming.

Uniwares_AS
1) it's actually uint, but nothing dictates that. 2) The current (only) implementation of EnumInterpreter does actually use Enum.GetName(), GetValue() doesn't exist. 3) Given that the EnumInterpreter CAN be passed in/overridden from the outside, I didn't want to be too trusting. 4) I work with people with that background, and they were here before me to decide the naming convention, but I'll check out your suggestion.
Benjol
Yeah, sorry, its actually .GetValues()
Uniwares_AS
A: 

I don't know whether to include this in my question, or as an answer. The problem is that it isn't THE answer, but it is the answer that works for me.

What I discovered, by chance while trying something else, is that if I just wodge it onto the end of a string, I get what I want:

throw new Exception("EnumInterpreter returns empty string for enumVal=" + enumVal);
//EnumInterpreter returns empty string for enumVal=3720116125

I actually simplified to int in my question, the real data type is uint (in this particular instance). Fortunately, given that I only actually wanted the string, I don't have to worry about that.

I'm not sure which of the three other answers is 'right', so vote away...

Benjol
A: 

Why not parse the enum to a string and return the actual enum value?

public enum MyEnum { Flower = 1, Tree = 2, Animal = 3 };

string name = MyEnum.Flower.ToString(); // returns "Flower"

I think .ToString() is depreciated and not sure on the new way to do it. I would of thought the actual enum representation would be more useful than the int?

mrnye
Because in the context of the code in question, I don't have access to the enum.
Benjol
A: 

try this..

m_EnumInterpreter((int) (object) enumVal);

Joo Park