Casting of Enum values

J

Jason Larion

When working with enums, I've noticed some behaviour that seems
completely counter-intuitive to me. I was wondering if someone here
could help restore my sanity, or at least help me to understand the
"why" of the behaviour.

After dimensioning an enum of type integer, any attribute referenced
seems to, by default, return the name of that attribute as a string,
instead of the integer value assigned to it.

The code snippet that follows demonstrates this behaviour.

Module enumtest

Private Enum Cheese As Integer
Cheddar = 1
Swiss = 2
Feta = 3
End Enum

Sub Main()


Debug.WriteLine(Cheese.Cheddar)
' "Cheddar" as System.String ...
' I expected "1" as System.Integer


'A More concrete example
Dim table As DataTable
Dim row As DataRow
Dim col As DataColumn


'Without DataType on column
table = New DataTable
col = New DataColumn

table.Columns.Add(col)

row = table.NewRow()

row.Item(0) = Cheese.Cheddar
Debug.WriteLine(row.Item(0)) ' "Cheddar" as System.String

row.Item(0) = CInt(Cheese.Cheddar)
Debug.WriteLine(row.Item(0)) ' "1" as System.Integer (Int32)


'With DateType on column
table = New DataTable
col = New DataColumn

col.DataType = GetType(System.Int32)
table.Columns.Add(col)

row = table.NewRow

row.Item(0) = Cheese.Cheddar
Debug.WriteLine(row.Item(0)) ' "1" as System.Integer (Int32)

row.Item(0) = CInt(Cheese.Cheddar)
Debug.WriteLine(row.Item(0)) ' "1" as System.Integer (Int32)

Exit Sub

End Sub

End Module


Thanks in advance for any help or insight that you can provice.

Regards,
Jason


MS DevEnv 2003 v7.1.3088
..NET Framework 1.2 v1.1.4322 SP1
 
C

Chris, Master of All Things Insignificant

AFAIK, The debug.writeline will make a call to the ToString() method of the
object passed in. If you want to see the number try this.

Debug.WriteLine(Cint(Cheese.Cheddar))

Didn't test it but it should write out the integer value of the enum.

Chris
 
M

Mattias Sjögren

Debug.WriteLine(Cint(Cheese.Cheddar))


The only downside with that solution is that it could fail if the
enum's underlying type is (U)Long (which it isn't here but could be in
the general case). An alternative is to use

Cheese.Cheddar.ToString("d", Nothing)



Mattias
 
M

Mythran

Mattias Sjögren said:
The only downside with that solution is that it could fail if the
enum's underlying type is (U)Long (which it isn't here but could be in
the general case). An alternative is to use

Cheese.Cheddar.ToString("d", Nothing)

Or just Cheese.Cheddar.ToString("d")

The second parameter belongs to the another overloaded ToString() method and
doesn't need to be included :)

Ex:

Enum Cheese As Integer
Cheddar = 1
Swiss = 2
American= 3
End Enum

Public Sub Main()
Dim myFav As Cheese = Cheese.American
Console.WriteLine(myFav.ToString("d"))
End Sub

Didn't test the above example, but I believe it's right ;)

Mythran
 
J

Jason Larion

Chris (et al),

That's exactly the surprising behaviour... I would think that anything
that calls ToString on it would return a string-formatted object of the
_value_, not the attribute.

I.e., in the example. "1" as String. Why do I get the attribute as
string? That's the part that I'm struggling with.

Thanks,
--Jason
 
P

Phill. W

Jason Larion said:
I would think that anything that calls ToString on it would return a
string-formatted object of the _value_, not the attribute.

Why do I get the attribute as string?
That's the part that I'm struggling with.

If you've gone to the trouble of defining an Enum, it's probably
because the "names" you've given to particular (or, more likely,
arbitrary) values are more "important" than the actual numerical
values themselves. After all, why not just use the numbers 1, 2,
3, etc. in your code? Because they're meaningless. "Cheddar",
"Swiss" and "Feta" enrich your code.

So it seems perfectly reasonable to me that calling ToString() on
an Enum value should give you the meaningful "name", rather than
some odd number "value".

Also, the "names" are more persistant. If you had, say, a Structure
containing values of your cheese Enum and saved it to a file, it
would [hopefully] save the Names, not the numerical values. Two
weeks down the line, you discover to your horror that you have to
redefine your Enum values. The "names" that you parse back out
of that file will /correctly/ map to their /new/ numerical values; if
you'd left the simple numbers in there, you'd be completely stuck.

HTH,
Phill W.
 
J

Jay B. Harlow [MVP - Outlook]

Jason,
In addition to the other comments:

The "Value" of the Enum IS the name!

The Cheese enum has 3 values: Cheddar, Swiss & Feta.

The fact that the Cheese.Cheddar value has a Integer representation of 1 is
an implementation detail, it could just as easily have a Byte representation
of 2 or a Long representation of
5,345,678,789,379,578 or even a Short representation of -5,789.

If you have a need for a constant Integer called Cheese with a value of 1,
then you may want to consider using a Constant instead!

Const Cheddar As Integer = 1


On a side note: IMHO Enum should support Char & String representations also,
but the designers of the framework did not have the foresight...

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top