Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Good Enum Question

Good Enum Question

Scheduled Pinned Locked Moved C#
questionhelp
8 Posts 7 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    Ed K
    wrote on last edited by
    #1

    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.

    E K L 3 Replies Last reply
    0
    • E Ed K

      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.

      E Offline
      E Offline
      Eric Gunnerson msft
      wrote on last edited by
      #2

      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.

      R J 2 Replies Last reply
      0
      • E Ed K

        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.

        K Offline
        K Offline
        KingTermite
        wrote on last edited by
        #3

        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.

        R 1 Reply Last reply
        0
        • E Eric Gunnerson msft

          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.

          R Offline
          R Offline
          ralfoide
          wrote on last edited by
          #4

          Could not the end-developper ideally control that using a compiler attribute? my 2 cents R/

          E 1 Reply Last reply
          0
          • E Eric Gunnerson msft

            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.

            J Offline
            J Offline
            J Dunlap
            wrote on last edited by
            #5

            I think it's a good idea. Those who don't like it can just not use it. :)

            "Do unto others as you would have them do unto you." - Jesus
            "An eye for an eye only makes the whole world blind." - Mahatma Gandhi

            1 Reply Last reply
            0
            • K KingTermite

              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.

              R Offline
              R Offline
              Rein Hillmann
              wrote on last edited by
              #6

              You'll always need to explicitly cast an int value to an enum unless the int value is zero.

              1 Reply Last reply
              0
              • R ralfoide

                Could not the end-developper ideally control that using a compiler attribute? my 2 cents R/

                E Offline
                E Offline
                Eric Gunnerson msft
                wrote on last edited by
                #7

                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.

                1 Reply Last reply
                0
                • E Ed K

                  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.

                  L Offline
                  L Offline
                  leppie
                  wrote on last edited by
                  #8

                  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.

                  leppie::AllocCPArticle(Generic DFA State Machine for .NET);

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups