Good Enum Question
-
One of the guys here posted a good question regarding enums. Basically questioning type safety with enums. Given the following:
using System; namespace Poker { class PokerTable { [STAThread] static void Main(string[] args) { // this errors PlayingCard fiveOfHearts = new PlayingCard( 4, 1 ); // works PlayingCard fiveOfHearts = new PlayingCard( (PlayingCard.Rank) 4, (PlayingCard.Suit) 1 ); fiveOfHearts.ViewHand(); // works PlayingCard rulesCard = new PlayingCard( (PlayingCard.Rank) 343, (PlayingCard.Suit) (-1) ); rulesCard.ViewHand(); // why does this work? PlayingCard emptyHand = new PlayingCard( 0, 0 ); emptyHand.ViewHand(); Console.In.ReadLine(); } } public class PlayingCard { public enum Suit { SPADES, HEARTS, DIAMONDS, CLUBS } public enum Rank { ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING } private Rank rank; private Suit suit; public PlayingCard( Rank rank, Suit suit ) { this.rank = rank; this.suit = suit; } public void ViewHand() { Console.WriteLine(rank + " " + suit); } } }
Why is PlayingCard( 0, 0 ) acceptable? Shouldn't this have a compile time error as does PlayingCard( 4, 1 )? I would think they should both fail! Thanks! ed Regulation is the substitution of error for chance.
-
One of the guys here posted a good question regarding enums. Basically questioning type safety with enums. Given the following:
using System; namespace Poker { class PokerTable { [STAThread] static void Main(string[] args) { // this errors PlayingCard fiveOfHearts = new PlayingCard( 4, 1 ); // works PlayingCard fiveOfHearts = new PlayingCard( (PlayingCard.Rank) 4, (PlayingCard.Suit) 1 ); fiveOfHearts.ViewHand(); // works PlayingCard rulesCard = new PlayingCard( (PlayingCard.Rank) 343, (PlayingCard.Suit) (-1) ); rulesCard.ViewHand(); // why does this work? PlayingCard emptyHand = new PlayingCard( 0, 0 ); emptyHand.ViewHand(); Console.In.ReadLine(); } } public class PlayingCard { public enum Suit { SPADES, HEARTS, DIAMONDS, CLUBS } public enum Rank { ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING } private Rank rank; private Suit suit; public PlayingCard( Rank rank, Suit suit ) { this.rank = rank; this.suit = suit; } public void ViewHand() { Console.WriteLine(rank + " " + suit); } } }
Why is PlayingCard( 0, 0 ) acceptable? Shouldn't this have a compile time error as does PlayingCard( 4, 1 )? I would think they should both fail! Thanks! ed Regulation is the substitution of error for chance.
Enums in C# do dual purpose. They are used for the usual enum use, and they're also used for bit fields. When I'm dealing with bit fields, you often want to AND a value with the bit field and check if it's true. Our initial rules meant that you had to write: if ((myVar & MyEnumName.ColorRed) != (MyEnumName) 0) which we thought was difficult to read. One alernative was to define a zero entry: if ((myVar & MyEnumName.ColorRed) != MyEnumName.NoBitsSet) which was also ugly. We therefore decided to relax our rules a bit, and permit an implicit conversion from the literal zero to any enum type, which allows you to write: if ((myVar & MyEnumName.ColorRed) != 0) which is why PlayingCard(0, 0) works.
-
One of the guys here posted a good question regarding enums. Basically questioning type safety with enums. Given the following:
using System; namespace Poker { class PokerTable { [STAThread] static void Main(string[] args) { // this errors PlayingCard fiveOfHearts = new PlayingCard( 4, 1 ); // works PlayingCard fiveOfHearts = new PlayingCard( (PlayingCard.Rank) 4, (PlayingCard.Suit) 1 ); fiveOfHearts.ViewHand(); // works PlayingCard rulesCard = new PlayingCard( (PlayingCard.Rank) 343, (PlayingCard.Suit) (-1) ); rulesCard.ViewHand(); // why does this work? PlayingCard emptyHand = new PlayingCard( 0, 0 ); emptyHand.ViewHand(); Console.In.ReadLine(); } } public class PlayingCard { public enum Suit { SPADES, HEARTS, DIAMONDS, CLUBS } public enum Rank { ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING } private Rank rank; private Suit suit; public PlayingCard( Rank rank, Suit suit ) { this.rank = rank; this.suit = suit; } public void ViewHand() { Console.WriteLine(rank + " " + suit); } } }
Why is PlayingCard( 0, 0 ) acceptable? Shouldn't this have a compile time error as does PlayingCard( 4, 1 )? I would think they should both fail! Thanks! ed Regulation is the substitution of error for chance.
I don't think so. Isn't 0 valid for both enums, but 4 is invalid for the first? Aren't the valid numbers for the Suit enum 0 - 3, while the valid numbers for the Rank enum 0 - 12 ? That's why you shouldn't use "number" to access. Always use them in the true OO model, like Rank.JACK instead of a number.
There are only 10 types of people in this world....those that understand binary, and those that do not.
-
Enums in C# do dual purpose. They are used for the usual enum use, and they're also used for bit fields. When I'm dealing with bit fields, you often want to AND a value with the bit field and check if it's true. Our initial rules meant that you had to write: if ((myVar & MyEnumName.ColorRed) != (MyEnumName) 0) which we thought was difficult to read. One alernative was to define a zero entry: if ((myVar & MyEnumName.ColorRed) != MyEnumName.NoBitsSet) which was also ugly. We therefore decided to relax our rules a bit, and permit an implicit conversion from the literal zero to any enum type, which allows you to write: if ((myVar & MyEnumName.ColorRed) != 0) which is why PlayingCard(0, 0) works.
-
Enums in C# do dual purpose. They are used for the usual enum use, and they're also used for bit fields. When I'm dealing with bit fields, you often want to AND a value with the bit field and check if it's true. Our initial rules meant that you had to write: if ((myVar & MyEnumName.ColorRed) != (MyEnumName) 0) which we thought was difficult to read. One alernative was to define a zero entry: if ((myVar & MyEnumName.ColorRed) != MyEnumName.NoBitsSet) which was also ugly. We therefore decided to relax our rules a bit, and permit an implicit conversion from the literal zero to any enum type, which allows you to write: if ((myVar & MyEnumName.ColorRed) != 0) which is why PlayingCard(0, 0) works.
-
I don't think so. Isn't 0 valid for both enums, but 4 is invalid for the first? Aren't the valid numbers for the Suit enum 0 - 3, while the valid numbers for the Rank enum 0 - 12 ? That's why you shouldn't use "number" to access. Always use them in the true OO model, like Rank.JACK instead of a number.
There are only 10 types of people in this world....those that understand binary, and those that do not.
You'll always need to explicitly cast an int value to an enum unless the int value is zero.
-
Could not the end-developper ideally control that using a compiler attribute? my 2 cents R/
It would be possible to allow the developer to control that behavior, but I think that allowing the user to change the language rules is a bad idea, as it complicates the language. Adding options often makes the user's lives harder, not easier.
-
One of the guys here posted a good question regarding enums. Basically questioning type safety with enums. Given the following:
using System; namespace Poker { class PokerTable { [STAThread] static void Main(string[] args) { // this errors PlayingCard fiveOfHearts = new PlayingCard( 4, 1 ); // works PlayingCard fiveOfHearts = new PlayingCard( (PlayingCard.Rank) 4, (PlayingCard.Suit) 1 ); fiveOfHearts.ViewHand(); // works PlayingCard rulesCard = new PlayingCard( (PlayingCard.Rank) 343, (PlayingCard.Suit) (-1) ); rulesCard.ViewHand(); // why does this work? PlayingCard emptyHand = new PlayingCard( 0, 0 ); emptyHand.ViewHand(); Console.In.ReadLine(); } } public class PlayingCard { public enum Suit { SPADES, HEARTS, DIAMONDS, CLUBS } public enum Rank { ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING } private Rank rank; private Suit suit; public PlayingCard( Rank rank, Suit suit ) { this.rank = rank; this.suit = suit; } public void ViewHand() { Console.WriteLine(rank + " " + suit); } } }
Why is PlayingCard( 0, 0 ) acceptable? Shouldn't this have a compile time error as does PlayingCard( 4, 1 )? I would think they should both fail! Thanks! ed Regulation is the substitution of error for chance.
Any enum is based on an integer type, which has a defualt value of 0, thus Enum as a ValueType it needs also some kind of default state, thus 0.