Cannot convert type 'System.Enum' to int
Asked Answered
W

8

42

(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').

Walczak answered 29/10, 2009 at 13:3 Comment(1)
possible duplicate of How to convert from System.Enum to base integer?Shieh
S
61

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)

Stevana answered 29/10, 2009 at 13:14 Comment(1)
C# enums cannot be floats: msdn.microsoft.com/en-us/library/sbbt4032%28VS.71%29.aspx - Every enumeration type has an underlying type, which can be any integral typeAtalayah
D
10

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.

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

int intVar = (int)enuYourEnum.GetType().GetField("value__").GetValue(objYourEnum);
Dulcedulcea answered 29/10, 2009 at 13:6 Comment(4)
Note that this will fail if int is not the underlying type of the enum.Bigwig
Well, I must confess that it isn't, it's a uint, but I think I've found something that works for me...Walczak
Does GetField() need BindingAttributes since value__ is private?Reclinate
why not just: (int)(object)enumValue?Deviltry
F
4

try this..

m_EnumInterpreter((int) (object) enumVal);

Foreman answered 1/6, 2010 at 22:56 Comment(0)
D
2

For me it was enough to cast to object first, since it's just a compilation error.

public static int AsInt(this Enum @this)
{
  return (int)(object)@this;
}
Deviltry answered 19/7, 2022 at 16:1 Comment(0)
D
1

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.

Declinate answered 29/10, 2009 at 13:36 Comment(2)
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.Walczak
Yeah, sorry, its actually .GetValues()Declinate
W
1

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...

Walczak answered 29/10, 2009 at 13:43 Comment(0)
T
0

I understand that this is probably not the solution to your exact problem, but I just want to post how I solved this for a particular API I was using.

int result = (int) (ActualEnumType) MethodThatReturnsSystemEnumType( arg1, arg2 );

Hopefully that will be of help to someone. Double cast FTW.

Tzong answered 8/4, 2014 at 11:19 Comment(0)
N
-6

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 deprecated and I'm not sure about the new way to do it. I would've thought the actual enum representation would be more useful than the int?

Naumachia answered 30/10, 2009 at 12:11 Comment(3)
Because in the context of the code in question, I don't have access to the enum.Walczak
Only one overload of .ToString() is actually deprecated - the intellisense is actually quite misleading in that regard.Riverside
"Why not parse the enum to a string and return the actual enum value?" - The underlying Int32 IS the actual enum value.Possie

© 2022 - 2024 — McMap. All rights reserved.