开发者

Using integer enum without casting in C#

开发者 https://www.devze.com 2023-01-26 14:19 出处:网络
Good afternoon, let\'s say I have the enum public enum Test : int { TestValue1 = 0, TestValue2, TestValue3

Good afternoon, let's say I have the enum

public enum Test : int 
{ 
   TestValue1 = 0, 
   TestValue2, 
   TestValue3 
}

Why can't I use statements like Int32 IntTest = Test.TestValue1 without a cast to mean IntTest = 0? It would be useful if I decided later to add more items to the enumeration开发者_JAVA百科? I think I am forced to use Int32 IntTest = (Int32) Test.TestValue1, which I think should be redundant... Also, why can't I make something like

switch (IntTest)
{
    case (Test.TestValue1) : DoSomething();
                             break;
    case (Test.TestValue2) : DoSomethingElse();
                             break;
    default                : Do Nothing();
}

? The compiler says it expects a constant value in the place of TestValue1... Isn't that value aready constant?

Thank you very much.


Note that you can do this:

switch ((Test)IntTest)
{
    case (Test.TestValue1) : DoSomething();
                             break;
    case (Test.TestValue2) : DoSomethingElse();
                             break;
    default                : DoNothing();
}

The cast to Test from int is guaranteed not to fail, even if the value is not present in the enumeration. If the value is not present in the enumeration, calling ToString() on the Test instance will return the string representation of the underlying numeric value.


You can't use Int32 and Test interchangeably because semantically they're different types, even if they do happen to use the same underlying storage mechanism.

If you need an Int32 then use an Int32; if you need a Test then use a Test; if you need to convert between them then use an explicit cast.

(And, of course, the language could easily have been spec'd to allow these conversions implicitly, but such a "feature" would probably create more problems than it solved.)


I wanted to implement an enum in the same way as this to simply make it easier to convert an application using table column names as strings to indexes.

This is what I'm trying to achieve:

enum TableName
{
    Column1Name = 0
}

Column1Data = (cast)objData[RowIndex][TableName.Column1Name];

the trouble as mentioned above is that C# requires an explicit cast when using enum's

Column1Data = (cast)objData[RowIndex][(int)TableName.Column1Name]; //what a waste of time..

But I've got a workaround.. moan all you want :P (this is not a production application - please think carefully about the impact of this code before implementing it in a live environment)

public static class TableName
{
    public const int Column1Name = 0;
}

Column1Data = (cast)objData[RowIndex][TableName.Column1Name]; //this is now valid, and my sanity remains intact - as does the integer value ;)


You have to cast because the language definition says you have to cast. Redundant? Maybe. But that's the way it is.

For your switch statement:

switch (IntTest)
{
    case (int)Test.TestValue1: DoSomething(); break;
}

Enum values must be fully qualified with the name of the enum type.


public enum Test
{ 
   TestValue1 = 0, 
   TestValue2, 
   TestValue3 
}

In a method you can use the enum as a Type.
Simply switch on a variable of type Test, then you do not need to cast the enum to an int.

public void DoSwitch(Test val)
{
   switch (val)
   {
       case (Test.TestValue1) : DoSomething();
                                break;
       case (Test.TestValue2) : DoSomethingElse();
                                break;
       default                : Do Nothing();
   }
}


enums works like that by design
As msdn says :

The underlying type specifies how much storage is allocated for each enumerator. However, an explicit cast is necessary to convert from enum type to an integral type.


Hey hey, I have just read this chapter in my book.

First thing I would like to mention you is trying this

Console.WriteLine(Test.TestValue1);

You will notice something.

The output is not a number or even an integer.

Besides, this should answer your second question too.

So you have to explicitly cast your enum to integer every time.

: )


As Paul pointed out you have a syntax error that should resolve ( which you have apparently fixed ). As other(s) have pointed out Test is an enumeration which holds the values of an integer. An enumeration can be used for example to handle values like x0001 or 0xA0BC (41148) easily.

In the example you used Int32 IntTest which is a 32-bit integer; I might add you should be using int instead of Int32 and unless your enumeration is holding something other then an integer don't even specify the : int since the default holding type is indeed integer.

With regards to the reason the compiler forces you to case the value; Its just how it works, an enumeration is NOT an integer, only the values of its possible sub-properties( TestValue1, TestValue2, TestValue3 ) are integers.*

As somebody pointed out what will be printed in a Console.WriteLine is not an integer.*


  • First, the : int part of your enum is completely redundant since int is the default governing type for enum already.

  • A cast is needed because when you write an enum, you are actually defining a new Type, much like a class. Any value of the enum named Test is of the type, Test.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号