This question already has answers here:
Why enums require an explicit cast to int type?
(7 answers)
Closed 6 years ago.
I can define an enum with integer as value:
public enum FieldType
{
Bar = 0,
Foo = 1
}
Why C# doesn't allow creating a dictionary with integer as a key and using an enum value when creating:
public Dictionary<int, Type> _fieldMapping = new Dictionary<int, Type>
{
{FieldType.Bar, null}, # Error in VS
{FieldType.Foo, null}, # Error in VS
}
I know i can do a cast, but i would like to know why enum cannot be converted to int implicitly when it actually is int under the hood.
If you could do that, you'd lose half the point of using enums at all - the point is to keep them as separate types to avoid you making mistakes involving using types incorrectly.
It seems to me like your dictionary should actually have FieldType as the key - at which point you'd have a safer approach. With your current expectation, you're expecting to be able to use any (int-based) enum type as the key, including things like FileShare which are clearly inappropriate.
So basically, you should ask yourself whether fundamentally you've got a map from field type to type, or whether you've really got a numeric map. To put it another way, without looking at FieldType at all, does an entry in the map from the number 1 to some Type mean anything? What does the 1 value represent there?
Related
This question already has answers here:
Casting value to T in a generic method
(6 answers)
Closed 2 years ago.
I'm writing code that avoids the overhead of Convert.ChangeType(). But I'm getting hung up one one little detail, which is illustrated below.
public void GetValue(out T value)
{
if (typeof(T) == typeof(string))
value = (T)""; // <== Cannot convert 'string' to 'T'
// ...
}
I have a value that I know is of type T, but how can I assign that value to an instance of type T with minimal overhead? I'm really hoping for something fast and simple. Otherwise, I'll scrap my code and use Convert.ChangeType() in a try...catch block.
You need to cast it to object first:
value = (T)(object)"";
Even though you've done a check for type compatibility the compiler doesn't look at this. As far as it's concerned you've got a T and a string which there isn't a direct cast. You have to bounce the string down to an object first (for which there is a direct cast) and then cast to T which as far as the compiler is concerned may fail, but won't because you've already checked the type!
Recently I've discovered that any string that contains only numeric characters can be converted to enum in C#. For example, imagine there is an enum defined as follows:
public enum TestEnum
{
One = 1,
Two = 2,
Three = 3
};
I can perform a conversion of some random numeric string to TestEnum.
TestEnum testEnum = (TestEnum)Enum.Parse(typeof(TestEnum), "4");
Console.WriteLine(testEnum);
The value '4' of course does not get mapped to one of defined TestEnum values and the output would be just 4, however there would be no error, so this conversion is legal.
On the other hand, if I try to check whether this value defined in TestEnum:
Console.WriteLine(Enum.IsDefined(typeof(TestEnum), "4"));
I would receive False in the output.
This seems a little strange to me, taking into account that the following conversion of non-numeric string, e.g.
(TestEnum)Enum.Parse(typeof(TestEnum), "Test")
will throw System.ArgumentException.
I am confused with such behavior. Was it intentionally designed this way or is this just a coincidence?
Was it intentionally designed this way or is this just a coincidence?
I'm not sure I understand your question. The documentation seems completely clear to me:
Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
(Emphasis mine)
It also says:
If value is the string representation of an integer that does not represent an underlying value of the enumType enumeration, the method returns an enumeration member whose underlying value is value converted to an integral type. If this behavior is undesirable, call the IsDefined method to ensure that a particular string representation of an integer is actually a member of enumType
Clearly this is intentional behavior, and not just coincidental.
Note that you can always cast any value of the enum's underlying type (int in this case), to the enum type itself. The enum type feature does not enforce values of the enum to correspond to named value. So the parsing behavior is entirely consistent with the compile-time behavior of enum types.
I suppose one might debate whether the enum type should allow unnamed values to be used. But, given that one of the features of enum types is to allow for flag-based enums, whether or not they have the [Flags] attribute, and given that it would be inconvenient (to say the least) to have to name every single combination of every single flag one defines in an enum type, it seems reasonable that they would go ahead and allow unnamed values for all types of enum types.
This question already has answers here:
How do ValueTypes derive from Object (ReferenceType) and still be ValueTypes?
(6 answers)
Closed 9 years ago.
In C# types are said to be of value and reference types
If System.Object is the topmost class so does it mean everything is object?
If its true ... then these questions come with them
1. so all types must be reference types as we cannot assign value directly to object .....
2.
int a=20; //this is primitive type or object ???
int a = new int(); //according to documentation this is reference type ...
How these two statements are different ... In first statement does the new keyword get automatically called?
Please explain this diagram its confusing me a lot ... couldn't understand from msdn.
Value types exist in two "flavors": As pure value types and as boxed values types. A boxed value type is an immutable reference object. Even if these two have a different "physical" nature, their logical C# type is the same. I.e. a boxed int is of type int. This is different from Java where there exists a logical value integer type and a logical reference integer type that are to related but distinct types.
To make this work, C# has an automatic boxing mechanism.
object o = 5; // Automatically boxes the integer number 5;
Unboxing must be specified explicitly:
int i = (int)o;
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.
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.