This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
convert an enum to another type of enum
When casting between enums of different types, is it possibly to directly cast from one type to the other like so?
LicenseTypes type;
TypeOfLicense type2;
type2 = (TypeOfLicense)type;
Or is it necessary to cast the enum to an int first? The compiler doesn't complain, but I want to make sure I'm not going to get some kind of funky casting exception at runtime.
This may seem like an odd thing to do, but both enums are identical in structure and value. Only the type names differ in this case.
Although its a duplicate and I have flagged it as well. You can do simple casting, beucase the underlying type is int, you can do:
LicenseTypes type = (LicenseTypes)TypeOfLicense.value3;
Here type will hold value '0';
Suppose you have:
public enum LicenseTypes
{
value1,
value2,
}
public enum TypeOfLicense
{
value3,
value4,
value5
}
But if you try to Cast TypeOfLicence.value5 then the variable type will hold the int value 2
LicenseTypes type = (LicenseTypes)TypeOfLicense.value5;
You can also look at this link for creating extension methods for conversion between enums. (Its the accepted answer of the similar question)
No, but you can do this making a few assumptions ...
LicenseTypes type = LicenseTypes.Type1;
TypeOfLicense type2 = TypeOfLicense.Type2;
type2 = (TypeOfLicense)(int)type;
... and those assumptions are this. We must assume that both LicenseTypes and TypeOfLicense base int for their value. We must also assume that casting the underlying values to one another correlate from a business perspective (but that's really neither here nor there from a technical perspective).
Please note this works for other base types and it is possible to build a more complex conversion that would allow you to cast between different types with conversions.
No matter how you do it, it is merely an assignment of integer to another variable. Remember, enums are internally treated as integers and hence it will make no difference.
Related
I'm attempting to write a DWARF parser in C#. DWARF has the concept of multiple numeric types (DW_FORM_data2, DW_FORM_data4, DW_FORM_data8, DW_FORM_sdata, DW_FORM_udata) which may all be resolved to enum types. I'd love to make an IConstant which the aforementioned DW_FORM_* classes implement which you can cast to an enum (just as you can cast ushort, int etc. to an enum).
However, a cast operator is a static method, and I can't put that on an enum. How does one go about making a group of numeric types which can be converted to enums? One complicating factor is that the size (8-bits, 32-bits, etc.) of a DW_FORM_udata or DW_FORM_sdata number isn't defined until it's decoded.
You can create a simple interface (not sure IConstant is the best name):
public interface IConstant {
TEnum ToEnum<TEnum>();
}
And then implement it in each of your numeric type classes, something like:
public TEnum ToEnum<TEnum>() {
return (TEnum)Enum.ToObject(typeof(TEnum), Value);
}
Then you can call it by specifying the enum type in the call:
var ev = data8.ToEnum<TestEnum>();
Without knowing the details of the classes, it is hard to say if you would be better off with an abstract class with a single implementation, if that is even possible.
Suppose I have enum, which underlying type is byte:
enum EmpType : byte
{
Manager = 1,
Worker = 2,
}
Can I cast some int literal to underlying type of this enum(byte in this case) ?
Something like this doesn't work (Error: "; expected"):
byte x = (Enum.GetUnderlyingType(typeof(EmpType)))15;
Can I cast to underlying type without explicitly writing (byte)15 ?
Thanks.
I think the following will work. But I'm not sure it will get you the desired behavior in all cases.
var x = Convert.ChangeType(15, Enum.GetUnderlyingType(typeof(EmpType)))
I'm not entirely sure what you're trying to do. Below is a related question about casting ints to enums and vice-versa, the same applies to byte in this case.
Is it possible to cast integer to enum?
If you want to detect the underlying type at run-time... it seems awkward and a lot of work. You could just do a case statement based upon the name of the underlying type. I'm not sure what good it would do you due to type safety concerns.
I have a enumerator which map to a bunch of int
example
enum MyEnum {
Open = 1,
Closed = 2,
Exit = 4
}
I find though that when I want to assign this to an integer, I have to cast it first.
int myEnumNumber = **(int)** MyEnum.Open;
Is it possible to specify the type of an enum so that it is implicit that there is a integer assigned to any value within the enum? That way, I do not need to keep casting it to an int if I want to use it
thanks
No, this is on purpose - enums have an underlying data type, but they are not considered to be identical, because this possibly creates lots of error possibilities that this way are simple to catch.
For example you say so much about having to cast the num all the time - I can not remember when I did do a cast of an enum last time. And I do a LOT of C# programming.
enum MyEnum : int
{
Open = 1,
Closed = 2,
Exit = 4
}
This is also mentioned here.
However, this does not allow you to avoid casting, this allows it to be used with types other than Int32 (which is the default enum type).
In short, yes, you can specify a type but no, you still have to cast it.
There are a few good reasons and probably a lot of bad ones for converting enum values to ints, I'll assume you have a good reason ;).
If you are doing a lot of int casting an extension method might be helpful, here is a quicky extension method:
public static int EnumCast(this Enum theEnum)
{
return (int)((IConvertible)theEnum);
}
And an example of usage in a test:
[Test]
public void EnumCastTest()
{
Assert.That(MyEnum.Exit.EnumCast(), Is.EqualTo(4));
}
You can specify a different underlying type using:
enum : byte MyEnum { ... }
But this does not remove the need to cast to byte (if you really want to). Enums in C# allow you to normally just forget about the underlying type unless your applciation requires it.
Do you really need the underlying integer? It is possible to actually store a string representation of an enumeration value in a database and then recreate the enumeration value from the string at a later point, see this question.
MSDN gives a good tutorial on the do's and don't of enums.
(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').
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)
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);
try this..
m_EnumInterpreter((int) (object) enumVal);
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.
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...
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;
}
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.
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?
Are C# enums typesafe?
If not what are the implications?
To give a slightly different answer... while the values are type-safe from the casting perspective, they are still unchecked once they have been cast - i.e.
enum Foo { A = 1, B = 2, C = 3 }
static void Main()
{
Foo foo = (Foo)500; // works fine
Console.WriteLine(foo); // also fine - shows 500
}
For this reason, you should take care to check the values - for example with a default in a switch that throws an exception.
You can also check the (for non-[Flags] values) via:
bool isValid = Enum.IsDefined(typeof(Foo), foo);
Yes they are.
The following is from http://www.csharp-station.com/Tutorials/Lesson17.aspx
Enums are strongly typed constants. They are essentially unique types that allow you to assign symbolic names to integral values. In the C# tradition, they are strongly typed, meaning that an enum of one type may not be implicitly assigned to an enum of another type even though the underlying value of their members are the same. Along the same lines, integral types and enums are not implicitly interchangable. All assignments between different enum types and integral types require an explicit cast.
For those suggesting to use Enum.IsDefined to do argument validation...don't! Per Brad Abrams (from the Framework Design Guidlines Update on Enum Design):
There are really two problems with Enum.IsDefined(). First it loads reflection and a bunch of cold type metadata making it a deceptively expensive call. Secondly, as the note alludes to there is a versioning issue here.
Yes.
C#: enum types:
-A type-safe enumeration of named values.
-Prevents programming errors
-User can control underlying type (defaults to int)
-Also can control underlying values
Technically no because you can represent an Enum as its base value (int, long, etc). However, if you ensure that you only use the enum by its provided names, you will receive compile time errors if you change the name of an enumerated value without updating its references. In this regard yes it is type safe.
I'm late to the party here, but I wanted to throw out a little something extra ... An update to the .NET Framework Design Guidelines from Krzysztof Cwalina. In addition to the excellent tip above on checking to ensure a valid value is passed to your Enums, this provides other guidance and advice for how to use them effectively, a bunch of gotchas (especially involved Flags enums), etc.
yes they r strongly-typed safed u cannot it does not do impilcit convertion of enum constant variables to integeral value u hv 2 expilcitly do dat
eg
enum days {
sun,
mon
}
int e = (int ) days.sun;
console.writeline(e);
C# enums are type safe meaning
You cannot implicitly convert from the underlying type to the actual enum
Also, you cannot assign a value of one enum to another enum, even though the underlying types of both the enums are same. An explicit cast is always required.
Enums make your code more readable and more maintainable.
I have come accross an excellent video tutorial on enums exaplaining their type safe nature. Have a look here and there.