Rationale behind int to enum casts

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andreas Huber

    Rationale behind int to enum casts

    Hi there

    Spending half an hour searching through the archive I haven't found a
    rationale for the following behavior.

    using System;

    // note the missing Flags attribute
    enum Color
    {
    Red,
    Green,
    Blue
    }

    class Whatever
    {
    static void Main()
    {
    // The following cast succeeds although the
    // value 42 does not exist.
    Color color = (Color) 42;
    Console.WriteLi ne( "{0}", color );
    }
    }

    I believe it would make my and other peoples life easier if that cast
    failed. Moreover, the framework does not even seem to offer a function
    to implement this directly. I have to roll my own, using
    Enum.IsDefined( ).

    What is the rationale for this?

    Thanks & Regards,

    Andreas
  • Zürcher See

    #2
    Re: Rationale behind int to enum casts

    Try to look at IConvertible

    "Andreas Huber" <ah2003@gmx.net > schrieb im Newsbeitrag
    news:3ede0f29.0 311260259.43b46 0fb@posting.goo gle.com...[color=blue]
    > Hi there
    >
    > Spending half an hour searching through the archive I haven't found a
    > rationale for the following behavior.
    >
    > using System;
    >
    > // note the missing Flags attribute
    > enum Color
    > {
    > Red,
    > Green,
    > Blue
    > }
    >
    > class Whatever
    > {
    > static void Main()
    > {
    > // The following cast succeeds although the
    > // value 42 does not exist.
    > Color color = (Color) 42;
    > Console.WriteLi ne( "{0}", color );
    > }
    > }
    >
    > I believe it would make my and other peoples life easier if that cast
    > failed. Moreover, the framework does not even seem to offer a function
    > to implement this directly. I have to roll my own, using
    > Enum.IsDefined( ).
    >
    > What is the rationale for this?
    >
    > Thanks & Regards,
    >
    > Andreas[/color]


    Comment

    • Miha Markic

      #3
      Re: Rationale behind int to enum casts

      Hi Andreas,

      Your enum is really an int.
      And the framework won't look if it is defined or not because of performance
      issue.
      Imagine this

      enum Tubo
      {
      Alfa = 11,
      Beta = 44
      }

      public void SomeMethod(int j)
      {
      int i = 5 * j;
      Tubo t = (Tubo)i;
      }

      It would be a big performance hit if runtime checks if it is valid or not...

      --
      Miha Markic - RightHand .NET consulting & software development
      miha at rthand com

      "Andreas Huber" <ah2003@gmx.net > wrote in message
      news:3ede0f29.0 311260259.43b46 0fb@posting.goo gle.com...[color=blue]
      > Hi there
      >
      > Spending half an hour searching through the archive I haven't found a
      > rationale for the following behavior.
      >
      > using System;
      >
      > // note the missing Flags attribute
      > enum Color
      > {
      > Red,
      > Green,
      > Blue
      > }
      >
      > class Whatever
      > {
      > static void Main()
      > {
      > // The following cast succeeds although the
      > // value 42 does not exist.
      > Color color = (Color) 42;
      > Console.WriteLi ne( "{0}", color );
      > }
      > }
      >
      > I believe it would make my and other peoples life easier if that cast
      > failed. Moreover, the framework does not even seem to offer a function
      > to implement this directly. I have to roll my own, using
      > Enum.IsDefined( ).
      >
      > What is the rationale for this?
      >
      > Thanks & Regards,
      >
      > Andreas[/color]


      Comment

      • Christoph Nahr

        #4
        Re: Rationale behind int to enum casts

        On Wed, 26 Nov 2003 14:49:38 +0100, "Miha Markic" <miha at rthand com>
        wrote:
        [color=blue]
        >It would be a big performance hit if runtime checks if it is valid or not...[/color]

        Only if you constantly convert from int to enum which you shouldn't be
        doing anyway because it defeats the point of having enums in the first
        place. At least in debug mode, the compiler or framework should check
        automatically that the value is actually valid.

        Again, the whole point of using enums instead of ints is type safety.
        I agree with Andreas that this behaviour is bizarre and should be
        fixed, performance hit or not.
        --
        Stay ahead in World of Warcraft with expert guides, latest patch news, class tips, dungeon strategies, PvP builds, and The War Within updates—all in one place.

        Comment

        • Uwe Hafner

          #5
          Re: Rationale behind int to enum casts

          Hi,

          "Christoph Nahr" <christoph.nahr @kynosarges.de> schrieb im Newsbeitrag
          news:poc9svce19 q6jar7eejikv1il ql76eg6s5@4ax.c om...[color=blue]
          > On Wed, 26 Nov 2003 14:49:38 +0100, "Miha Markic" <miha at rthand com>
          > wrote:
          >
          > I agree with Andreas that this behaviour is bizarre and should be
          > fixed, performance hit or not.[/color]

          There is nothing to "fix". This is a documented behaviour.

          From MSDN:
          MSDN .NET Framework General Reference
          Value Type Usage Guidelines

          <quote>
          Do not assume that enum arguments will be in the defined range. It is valid
          to cast any integer value into an enum even if the value is not defined in
          the enum. Perform argument validation as illustrated in the following code
          example.
          [Visual Basic]
          Public Sub SetColor(newCol or As Color)
          If Not [Enum].IsDefined(GetT ype(Color), newColor) Then
          Throw New ArgumentOutOfRa ngeException()
          End If
          End Sub
          [C#]
          public void SetColor (Color color)
          {
          if (!Enum.IsDefine d (typeof(Color), color)
          throw new ArgumentOutOfRa ngeException();
          }
          </quote>

          hth
          Uwe


          Comment

          • Eric Gunnerson [MS]

            #6
            Re: Rationale behind int to enum casts

            Enums are used both for a set of enumerated values, and for bit fields. In
            the bit fields case, you need to be able to represent values that aren't
            equal to one of the defined constants.

            You can use the static methods on the Enum class to see if a specific value
            is equal to one of the predefined constant values.

            --
            Eric Gunnerson

            Visit the C# product team at http://www.csharp.net
            Eric's blog is at http://blogs.gotdotnet.com/ericgu/

            This posting is provided "AS IS" with no warranties, and confers no rights.
            "Andreas Huber" <ah2003@gmx.net > wrote in message
            news:3ede0f29.0 311260259.43b46 0fb@posting.goo gle.com...[color=blue]
            > Hi there
            >
            > Spending half an hour searching through the archive I haven't found a
            > rationale for the following behavior.
            >
            > using System;
            >
            > // note the missing Flags attribute
            > enum Color
            > {
            > Red,
            > Green,
            > Blue
            > }
            >
            > class Whatever
            > {
            > static void Main()
            > {
            > // The following cast succeeds although the
            > // value 42 does not exist.
            > Color color = (Color) 42;
            > Console.WriteLi ne( "{0}", color );
            > }
            > }
            >
            > I believe it would make my and other peoples life easier if that cast
            > failed. Moreover, the framework does not even seem to offer a function
            > to implement this directly. I have to roll my own, using
            > Enum.IsDefined( ).
            >
            > What is the rationale for this?
            >
            > Thanks & Regards,
            >
            > Andreas[/color]


            Comment

            • Christoph Nahr

              #7
              Re: Rationale behind int to enum casts

              On Wed, 26 Nov 2003 17:23:15 +0100, "Uwe Hafner"
              <SpamUrSelf@NOS PAM.de> wrote:
              [color=blue]
              >There is nothing to "fix". This is a documented behaviour.[/color]

              Yes... we disagree with that documented behaviour, and consider it
              broken, hence we want a "fix".
              --
              Stay ahead in World of Warcraft with expert guides, latest patch news, class tips, dungeon strategies, PvP builds, and The War Within updates—all in one place.

              Comment

              • Christoph Nahr

                #8
                Re: Rationale behind int to enum casts

                On Wed, 26 Nov 2003 12:54:03 -0800, "Eric Gunnerson [MS]"
                <ericgu@online. microsoft.com> wrote:
                [color=blue]
                >Enums are used both for a set of enumerated values, and for bit fields. In
                >the bit fields case, you need to be able to represent values that aren't
                >equal to one of the defined constants.[/color]

                But bit field enums are always indicated by the [Flags] attribute,
                correct? It should be easy enough to auto-generate a conversion check
                if that attribute is not present.
                --
                Stay ahead in World of Warcraft with expert guides, latest patch news, class tips, dungeon strategies, PvP builds, and The War Within updates—all in one place.

                Comment

                • Miha Markic

                  #9
                  Re: Rationale behind int to enum casts

                  Hi Chris,

                  "Christoph Nahr" <christoph.nahr @kynosarges.de> wrote in message
                  news:id8bsv409e h2el3l2d7iq0uol n2aqg0tot@4ax.c om...[color=blue]
                  > On Wed, 26 Nov 2003 12:54:03 -0800, "Eric Gunnerson [MS]"
                  > <ericgu@online. microsoft.com> wrote:
                  >[color=green]
                  > >Enums are used both for a set of enumerated values, and for bit fields.[/color][/color]
                  In[color=blue][color=green]
                  > >the bit fields case, you need to be able to represent values that aren't
                  > >equal to one of the defined constants.[/color]
                  >
                  > But bit field enums are always indicated by the [Flags] attribute,
                  > correct? It should be easy enough to auto-generate a conversion check
                  > if that attribute is not present.[/color]

                  Not really.
                  FlagsAttribute is just a descriptor - used by some function (for text output
                  (ToString) if I remember correctly).
                  You can safely use enums for flags without FlagsAttribute.

                  --
                  Miha Markic - RightHand .NET consulting & software development
                  miha at rthand com


                  Comment

                  • Andreas Huber

                    #10
                    Re: Rationale behind int to enum casts

                    Eric,
                    [color=blue]
                    > Enums are used both for a set of enumerated values, and for bit fields. In
                    > the bit fields case, you need to be able to represent values that aren't
                    > equal to one of the defined constants.[/color]

                    I know, I'm wondering why C# behaves this way __even if I don't put a
                    Flags attribute__ on my enum. This doesn't make a lot of sense to
                    me...

                    Thanks & Regards,

                    Andreas

                    Comment

                    • Matt

                      #11
                      Re: Rationale behind int to enum casts

                      ah2003@gmx.net (Andreas Huber) wrote in message news:<3ede0f29. 0311260259.43b4 60fb@posting.go ogle.com>...[color=blue]
                      > I believe it would make my and other peoples life easier if that cast
                      > failed. Moreover, the framework does not even seem to offer a function
                      > to implement this directly. I have to roll my own, using
                      > Enum.IsDefined( ).[/color]

                      I had a similar discussion about this a while back, so the following
                      may be of interest to you:

                      [watch out for wordwrap]

                      Regards,

                      Matt

                      Comment

                      • Christoph Nahr

                        #12
                        Re: Rationale behind int to enum casts

                        On Thu, 27 Nov 2003 09:50:23 +0100, "Miha Markic" <miha at rthand com>
                        wrote:
                        [color=blue]
                        >FlagsAttribu te is just a descriptor - used by some function (for text output
                        >(ToString) if I remember correctly).
                        >You can safely use enums for flags without FlagsAttribute.[/color]

                        Okay, but who does this? IMO it would be safe to restrict the language
                        definition so that Flags is required for bitwise combinable flags. The
                        compiler could then react to the absence of the attribute by providing
                        a custom base-type-to-enum conversion with range-checking code.
                        --
                        Stay ahead in World of Warcraft with expert guides, latest patch news, class tips, dungeon strategies, PvP builds, and The War Within updates—all in one place.

                        Comment

                        • Miha Markic

                          #13
                          Re: Rationale behind int to enum casts

                          I've always liked Delphi sets :)

                          --
                          Miha Markic - RightHand .NET consulting & software development
                          miha at rthand com

                          "Christoph Nahr" <christoph.nahr @kynosarges.de> wrote in message
                          news:8v0csv8cm5 epifm0fuihq3ffq 5ekasuv35@4ax.c om...[color=blue]
                          > On Thu, 27 Nov 2003 09:50:23 +0100, "Miha Markic" <miha at rthand com>
                          > wrote:
                          >[color=green]
                          > >FlagsAttribu te is just a descriptor - used by some function (for text[/color][/color]
                          output[color=blue][color=green]
                          > >(ToString) if I remember correctly).
                          > >You can safely use enums for flags without FlagsAttribute.[/color]
                          >
                          > Okay, but who does this? IMO it would be safe to restrict the language
                          > definition so that Flags is required for bitwise combinable flags. The
                          > compiler could then react to the absence of the attribute by providing
                          > a custom base-type-to-enum conversion with range-checking code.
                          > --
                          > http://www.kynosarges.de[/color]


                          Comment

                          • Daniel O'Connell

                            #14
                            Re: Rationale behind int to enum casts


                            "Christoph Nahr" <christoph.nahr @kynosarges.de> wrote in message
                            news:8v0csv8cm5 epifm0fuihq3ffq 5ekasuv35@4ax.c om...[color=blue]
                            > On Thu, 27 Nov 2003 09:50:23 +0100, "Miha Markic" <miha at rthand com>
                            > wrote:
                            >[color=green]
                            > >FlagsAttribu te is just a descriptor - used by some function (for text[/color][/color]
                            output[color=blue][color=green]
                            > >(ToString) if I remember correctly).
                            > >You can safely use enums for flags without FlagsAttribute.[/color]
                            >
                            > Okay, but who does this? IMO it would be safe to restrict the language
                            > definition so that Flags is required for bitwise combinable flags. The
                            > compiler could then react to the absence of the attribute by providing
                            > a custom base-type-to-enum conversion with range-checking code.[/color]

                            Which is fine until you have to use a VB, or C++, or any other language
                            library and cannot perform bitwise combinations because that language
                            doesn't force the Flags attribute. It cannot be a single langauge thing, it
                            would have to be defined in the CLS. If you cannot rely on your enums being
                            created IN C#, so you cannot rely on a language specification to handle this
                            situation, the runtime and all assocaited languages would have to use it.
                            And I personally don't want to have to cast every enum to int to perform a
                            bitwise operation and cast back to the enum.
                            Frankly, I consider the lack of member value checking a nicety. There are
                            times when using a bit flagged set of options where you will have flags set
                            that aren't considred in the current version, but are irrelevent and can be
                            ignored, having to write code to mask out all possible invalid flags is a
                            pain and will result in incorrect flags set when persisted.
                            [color=blue]
                            > --
                            > http://www.kynosarges.de[/color]


                            Comment

                            • Andreas Huber

                              #15
                              Re: Rationale behind int to enum casts

                              Daniel,
                              [color=blue][color=green]
                              > > Okay, but who does this? IMO it would be safe to restrict the language
                              > > definition so that Flags is required for bitwise combinable flags. The
                              > > compiler could then react to the absence of the attribute by providing
                              > > a custom base-type-to-enum conversion with range-checking code.[/color]
                              >
                              > Which is fine until you have to use a VB, or C++, or any other language
                              > library and cannot perform bitwise combinations because that language
                              > doesn't force the Flags attribute. It cannot be a single langauge thing, it
                              > would have to be defined in the CLS.[/color]

                              Easy: Enums lacking a Flags attribute would not be CLS compliant. It's
                              the same situation with unsigned/signed ints: The whole .NET framework
                              uses only signed ints. However, C#-only stuff can use unsigned ints,
                              which means that such code cannot be consumed by languages like VB.

                              Of course the CLR would have to support two types of enums:
                              - A strict one that is always checked and thus only usable for
                              ordinary enums.
                              - A nonstrict one that is never checked and thus usable for both
                              ordinary and bitflagged enums.
                              Depending on the language, either the strict or the non-strict one is
                              emitted by default. In C# this would be the strict variant, adding a
                              Flags attribute would make it a non-strict one what also makes it
                              consumeable by other languages.
                              [color=blue]
                              > And I personally don't want to have to cast every enum to int to perform a
                              > bitwise operation and cast back to the enum.
                              > Frankly, I consider the lack of member value checking a nicety. There are
                              > times when using a bit flagged set of options where you will have flags set
                              > that aren't considred in the current version, but are irrelevent and can be
                              > ignored, having to write code to mask out all possible invalid flags is a
                              > pain and will result in incorrect flags set when persisted.[/color]

                              The checking would only be done for enums lacking the Flags attribute,
                              enums with the Flags attribute would not be checked. This way the
                              programmer has full control.

                              Regards,

                              Andreas

                              Comment

                              Working...