is there a less verbose way to cast and use enums?

  • Thread starter Thread starter Yechezkal Gutfreund
  • Start date Start date
Y

Yechezkal Gutfreund

this.stateCode == (int)Common.stateCodes.shutdown

All stateCodes is a a shared enum across my classes that has integer values
for the link state.

is there not a less verbose way to do this, other than to do the cast each
time?
 
Less verbose than (int) ? That's 5 chars :). Not that I know of. I guess
you could create a method called X that does the cast for you -- that'd save
2 chars.

-mike
MVP
 
Yechezkal Gutfreund said:
this.stateCode == (int)Common.stateCodes.shutdown

All stateCodes is a a shared enum across my classes that has integer values
for the link state.

is there not a less verbose way to do this, other than to do the cast each
time?

You'll need to cast every time, but you could get rid of the Common if
you declare the enum directly in the namespace.
 
Common is in the namespace. Thank you.

Syntacly speaking, I was also hoping to get rid of the cast.

The ability to specify the type with the enum declaration seems
useless. What else is it good for?

enum stateCodes: int {
connected,
attached,
closed,
}

Since I was explicit in the declaration, it should understand this is the
way I want
to use it. right? (obviously not!)
 
No. Int is the basis for the enum. Since the CLR needs type safety, an
enum is an enum, and NOT an int, even if it's easily cast to one. This is a
design *feature*, not a flaw :).

-mike
MVP

Yechezkal Gutfreund said:
Common is in the namespace. Thank you.

Syntacly speaking, I was also hoping to get rid of the cast.

The ability to specify the type with the enum declaration seems
useless. What else is it good for?

enum stateCodes: int {
connected,
attached,
closed,
}

Since I was explicit in the declaration, it should understand this is the
way I want
to use it. right? (obviously not!)
 
Yechezkal,
Define stateCode as stateCodes and not as an int!

class SomeClass
{
private Common.StateCodes stateCode;

public void SomeMethod()
{
this.stateCode = Common.StateCodes.shutdown
}

}

As Michael stated, an enum is an Enum, not an integer!

Hope this helps
Jay
 
Hi Jay

That works great if you can guarantee the value to always be a member of the
enum. But if it came from an untrusted source (e.g. A database field that
may have been changed with SQL Analyser), you will need a try/catch round
the statement to catch the invalid cast exception - verbosity wins again...

Which leads me to a related question: Is there an elegant way of testing
that a value is a member of an enum? Obviously looping through all values
would work, but is there a better way?

Regards

Ron
 
enumVar = [Enum].Parse(enumVar.GetType, "SomeenumName")

do u want something like this???
 
Ron,
may have been changed with SQL Analyser), you will need a try/catch round
the statement to catch the invalid cast exception - verbosity wins
again...
What statement?

I really do not know when the above statement would ever throw an exception!
Also note I am assign an enum value to an enum field, verbosity is NOT part
of the picture!
Which leads me to a related question: Is there an elegant way of testing
that a value is a member of an enum? Obviously looping through all values
would work, but is there a better way?
Remember you can assign any value you want to an Enum field, even if that
value is not part of the enum itself. The only restriction is the value fits
in the underlying field type (byte, int, short).

I would recommend Enum.IsDefined, alternatively you could wrap Enum.Parse,
or Enum.ToObject in a try catch. Enum.Parse is handy when you have a string,
Enum.ToObject is handy when you have an integer.

Hope this helps
Jay
 
Yechezkal Gutfreund said:
Common is in the namespace. Thank you.

Syntacly speaking, I was also hoping to get rid of the cast.

The ability to specify the type with the enum declaration seems
useless. What else is it good for?

enum stateCodes: int {
connected,
attached,
closed,
}

Since I was explicit in the declaration, it should understand this is the
way I want to use it. right? (obviously not!)

No. The point of specifying the type is so the CLR knows how to store
the values. For instance, you could have them as bytes rather than
ints.

However, the reason you have to cast is for type safety - otherwise I
could do:

stateCodes x = BindingFlags.Public;

which would be a thoroughly bad thing.
 
You don't need the cast if the types are the same! Define this.stateCode as
type stateCodes.

brian

Yechezkal Gutfreund said:
Common is in the namespace. Thank you.

Syntacly speaking, I was also hoping to get rid of the cast.

The ability to specify the type with the enum declaration seems
useless. What else is it good for?

enum stateCodes: int {
connected,
attached,
closed,
}

Since I was explicit in the declaration, it should understand this is the
way I want
to use it. right? (obviously not!)
 
I have a related question. I wrote the following code:

enum testEnum {a = 1, b = 2, c = 3}
private void TestIt()
{
int z = 10;
testEnum t = (testEnum)z;
Debug.WriteLine(t.ToString();
}

When I call TestIt(), no exception is thrown and the WriteLine sends "10" to
the output window. This seems wrong to me, as I'd expect a runtime
exception to be thrown when the assigned value isn't a member of the enum.
Perhaps it's just to costly to check? Thoughts?
Tom Clement
Apptero, Inc.
 
Tom,
There are no runtime checks performed on assignments to Enum, 10 may be a
valid value in that the enum may be a bit mask.

[Flags] enum testFlags = { a = 1, b = 2, c = 4, d = 8 }

10 would represent the value which include both b & d.

You can use the System.Enum.IsDefined to ensure that the value is a valid
enum amount.

Hope this helps
Jay
 
Hi Jay,
I guess I hadn't really thought about it that way. It does makes sense for
[Flags] attributed enums. My shorthand way of thinking of enums was as
programmer-defined named and constrained integral types, which I now see
isn't very accurate. Thanks for the clarification.
Tom Clement
Apptero, Inc.


Jay B. Harlow said:
Tom,
There are no runtime checks performed on assignments to Enum, 10 may be a
valid value in that the enum may be a bit mask.

[Flags] enum testFlags = { a = 1, b = 2, c = 4, d = 8 }

10 would represent the value which include both b & d.

You can use the System.Enum.IsDefined to ensure that the value is a valid
enum amount.

Hope this helps
Jay

Tom Clement said:
I have a related question. I wrote the following code:

enum testEnum {a = 1, b = 2, c = 3}
private void TestIt()
{
int z = 10;
testEnum t = (testEnum)z;
Debug.WriteLine(t.ToString();
}

When I call TestIt(), no exception is thrown and the WriteLine sends
"10"
to
the output window. This seems wrong to me, as I'd expect a runtime
exception to be thrown when the assigned value isn't a member of the enum.
Perhaps it's just to costly to check? Thoughts?
Tom Clement
Apptero, Inc.


of
the
 
Tom,
I would prefer Enum to be more strongly typed, and less "int" like myself
also. In that they are not specifically based on Integer values, allow Char
& String values also!

However the CLR designers choose not to go that route, I suspect to allow
more languages to make use of them...

Just a thought
Jay

Tom Clement said:
Hi Jay,
I guess I hadn't really thought about it that way. It does makes sense for
[Flags] attributed enums. My shorthand way of thinking of enums was as
programmer-defined named and constrained integral types, which I now see
isn't very accurate. Thanks for the clarification.
Tom Clement
Apptero, Inc.


Tom,
There are no runtime checks performed on assignments to Enum, 10 may be a
valid value in that the enum may be a bit mask.

[Flags] enum testFlags = { a = 1, b = 2, c = 4, d = 8 }

10 would represent the value which include both b & d.

You can use the System.Enum.IsDefined to ensure that the value is a valid
enum amount.

Hope this helps
Jay

Tom Clement said:
I have a related question. I wrote the following code:

enum testEnum {a = 1, b = 2, c = 3}
private void TestIt()
{
int z = 10;
testEnum t = (testEnum)z;
Debug.WriteLine(t.ToString();
}

When I call TestIt(), no exception is thrown and the WriteLine sends
"10"
to
the output window. This seems wrong to me, as I'd expect a runtime
exception to be thrown when the assigned value isn't a member of the enum.
Perhaps it's just to costly to check? Thoughts?
Tom Clement
Apptero, Inc.


Hi Jay

That works great if you can guarantee the value to always be a
member
 
Thanks Jay. Seems that others expected a run-time exception too. I come from
a Delphi background, where enums are tightly range-checked. I sort of
expected the CLR to be similar - but it is not.

Thanks for the tip on using Enum.IsDefined()

Regards

Ron
 
And thank you guys, I am an old-timer and then to think in terms of C
#define statements. You also clued me into ToString() and Parse() which
might be very useful.

The only issue is that my application talks between a CF and a
DotNetFramework.

and Parse() is not supported on CF. It seems like it would be not that
difficult to do. (a little tricky to do efficiently though, and aslo a bit
of fun). But just to check. has someone done this already? (getNames does
not work either).
 
Back
Top