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. The Lounge
  3. Does this language feature seem strange to anyone else?

Does this language feature seem strange to anyone else?

Scheduled Pinned Locked Moved The Lounge
csharpdatabasedesignhelpquestion
24 Posts 10 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.
  • L Offline
    L Offline
    lewax00
    wrote on last edited by
    #1

    Part of an application I work on involves navigation through a series of documents, previously the navigate function looked like:

    void NavigateTo(int document)

    but as part of a redesign that made a single numeric index lose it's meaning, I changed it to

    void NavigateTo(NavigationDirection direction)

    where NavigationDirection is an enum consisting of Forward and Backward. As expected, the change caused some compilation errors where it was being called, because C# doesn't allow implicit conversion of int to enum. Having written the section of code it was in, I was pretty sure I knew where all the calls were, and the compiler seemed to agree...but the navigation was acting funny, it started at the second document. Debugged it, and found a third call to the function, that looked like this:

    NavigateTo(0);

    and 0 was the value of Forward, which was then moving it to the 2nd document, added a third value to the enum, None, since the first document was already being loaded in a new way, and this was just moving past it (the navigation has some side effects, loading other things related to the document, so the call was still needed...it makes more sense in the actual code, I'm just simplifying it). But hold on, I thought there wasn't an implicit conversion from int to enum types in C#? So I played around with it a bit, and here's what I discovered: ints are not implicitly convertible to enum types (as I thought)...but const ints are 0 is! Both integer literals, and const int variables, as long as the value maps to a value in the enum (if it had been a number greater than 1 other than 0, I would have had the expected compiler error). While I understand how the compiler can implement this, I don't understand why they would, it seems to go against the C# language itself. I don't think you could even write your own implicit conversion that behaves the same way, since from what I can tell C# doesn't generally make a distinction between const and non-const versions of the same type for the purposes of parameters (e.g. int and const int can be used interchangeably), with the exception of ref and out...but that causes restriction in the reverse direction (only non-const). Seems like an odd language design choice to me :doh: EDIT: looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

    P A J C E 7 Replies Last reply
    0
    • L lewax00

      Part of an application I work on involves navigation through a series of documents, previously the navigate function looked like:

      void NavigateTo(int document)

      but as part of a redesign that made a single numeric index lose it's meaning, I changed it to

      void NavigateTo(NavigationDirection direction)

      where NavigationDirection is an enum consisting of Forward and Backward. As expected, the change caused some compilation errors where it was being called, because C# doesn't allow implicit conversion of int to enum. Having written the section of code it was in, I was pretty sure I knew where all the calls were, and the compiler seemed to agree...but the navigation was acting funny, it started at the second document. Debugged it, and found a third call to the function, that looked like this:

      NavigateTo(0);

      and 0 was the value of Forward, which was then moving it to the 2nd document, added a third value to the enum, None, since the first document was already being loaded in a new way, and this was just moving past it (the navigation has some side effects, loading other things related to the document, so the call was still needed...it makes more sense in the actual code, I'm just simplifying it). But hold on, I thought there wasn't an implicit conversion from int to enum types in C#? So I played around with it a bit, and here's what I discovered: ints are not implicitly convertible to enum types (as I thought)...but const ints are 0 is! Both integer literals, and const int variables, as long as the value maps to a value in the enum (if it had been a number greater than 1 other than 0, I would have had the expected compiler error). While I understand how the compiler can implement this, I don't understand why they would, it seems to go against the C# language itself. I don't think you could even write your own implicit conversion that behaves the same way, since from what I can tell C# doesn't generally make a distinction between const and non-const versions of the same type for the purposes of parameters (e.g. int and const int can be used interchangeably), with the exception of ref and out...but that causes restriction in the reverse direction (only non-const). Seems like an odd language design choice to me :doh: EDIT: looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

      P Offline
      P Offline
      PIEBALDconsult
      wrote on last edited by
      #2

      It's horrible; has no benefit and causes nothing but trouble. I'm still unsure that anyone pointed me to documentation on it though. http://www.codeproject.com/Lounge.aspx?msg=4201677#xx4201677xx[^]

      L 1 Reply Last reply
      0
      • L lewax00

        Part of an application I work on involves navigation through a series of documents, previously the navigate function looked like:

        void NavigateTo(int document)

        but as part of a redesign that made a single numeric index lose it's meaning, I changed it to

        void NavigateTo(NavigationDirection direction)

        where NavigationDirection is an enum consisting of Forward and Backward. As expected, the change caused some compilation errors where it was being called, because C# doesn't allow implicit conversion of int to enum. Having written the section of code it was in, I was pretty sure I knew where all the calls were, and the compiler seemed to agree...but the navigation was acting funny, it started at the second document. Debugged it, and found a third call to the function, that looked like this:

        NavigateTo(0);

        and 0 was the value of Forward, which was then moving it to the 2nd document, added a third value to the enum, None, since the first document was already being loaded in a new way, and this was just moving past it (the navigation has some side effects, loading other things related to the document, so the call was still needed...it makes more sense in the actual code, I'm just simplifying it). But hold on, I thought there wasn't an implicit conversion from int to enum types in C#? So I played around with it a bit, and here's what I discovered: ints are not implicitly convertible to enum types (as I thought)...but const ints are 0 is! Both integer literals, and const int variables, as long as the value maps to a value in the enum (if it had been a number greater than 1 other than 0, I would have had the expected compiler error). While I understand how the compiler can implement this, I don't understand why they would, it seems to go against the C# language itself. I don't think you could even write your own implicit conversion that behaves the same way, since from what I can tell C# doesn't generally make a distinction between const and non-const versions of the same type for the purposes of parameters (e.g. int and const int can be used interchangeably), with the exception of ref and out...but that causes restriction in the reverse direction (only non-const). Seems like an odd language design choice to me :doh: EDIT: looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

        A Offline
        A Offline
        AspDotNetDev
        wrote on last edited by
        #3

        I'd call them "integer literal" and "integer variable" rather than "integer const" and "integer variable". But yeah, that's an interesting nuance, and I don't think implicit conversion operators can make a distinct between literals/variables. However, expression trees might be able to (though that is a runtime construct, not a compile time one). Also, I wonder if Roslyn would allow for knowledge of literals/variables.

        Thou mewling ill-breeding pignut!

        L 1 Reply Last reply
        0
        • P PIEBALDconsult

          It's horrible; has no benefit and causes nothing but trouble. I'm still unsure that anyone pointed me to documentation on it though. http://www.codeproject.com/Lounge.aspx?msg=4201677#xx4201677xx[^]

          L Offline
          L Offline
          lewax00
          wrote on last edited by
          #4

          There was something brought up there I didn't test...it is exclusive to 0. That is even worse. Even if I explicitly set the values of the enum so none of them are 0, 0 is still valid, but other ones are not even if they exist...but it gets worse. If there isn't one for 0, it just becomes the value 0 (which won't likely be handled by a function expecting a proper enum value), but if it does it becomes that enum value instead. Wat. :doh:

          A M M 3 Replies Last reply
          0
          • L lewax00

            There was something brought up there I didn't test...it is exclusive to 0. That is even worse. Even if I explicitly set the values of the enum so none of them are 0, 0 is still valid, but other ones are not even if they exist...but it gets worse. If there isn't one for 0, it just becomes the value 0 (which won't likely be handled by a function expecting a proper enum value), but if it does it becomes that enum value instead. Wat. :doh:

            A Offline
            A Offline
            AspDotNetDev
            wrote on last edited by
            #5

            According to this, zero is basically the enum version of a default/null value. Not that it makes any more sense, but that seems to be the reason they allow for zero as a value for enums.

            Thou mewling ill-breeding pignut!

            L P 2 Replies Last reply
            0
            • A AspDotNetDev

              I'd call them "integer literal" and "integer variable" rather than "integer const" and "integer variable". But yeah, that's an interesting nuance, and I don't think implicit conversion operators can make a distinct between literals/variables. However, expression trees might be able to (though that is a runtime construct, not a compile time one). Also, I wonder if Roslyn would allow for knowledge of literals/variables.

              Thou mewling ill-breeding pignut!

              L Offline
              L Offline
              lewax00
              wrote on last edited by
              #6

              A constant integer and and integer literal are two different things though (at compile time anyways, they may not be by run time, depending on what the compiler does with them). And both are valid in this context, e.g. in

              const int i = 0;
              EnumType e0 = 0;
              EnumType e1 = i;

              both assignments to the EnumType are valid.

              A 1 Reply Last reply
              0
              • L lewax00

                A constant integer and and integer literal are two different things though (at compile time anyways, they may not be by run time, depending on what the compiler does with them). And both are valid in this context, e.g. in

                const int i = 0;
                EnumType e0 = 0;
                EnumType e1 = i;

                both assignments to the EnumType are valid.

                A Offline
                A Offline
                AspDotNetDev
                wrote on last edited by
                #7

                Ah, gotcha.

                Thou mewling ill-breeding pignut!

                1 Reply Last reply
                0
                • L lewax00

                  There was something brought up there I didn't test...it is exclusive to 0. That is even worse. Even if I explicitly set the values of the enum so none of them are 0, 0 is still valid, but other ones are not even if they exist...but it gets worse. If there isn't one for 0, it just becomes the value 0 (which won't likely be handled by a function expecting a proper enum value), but if it does it becomes that enum value instead. Wat. :doh:

                  M Offline
                  M Offline
                  Matthew Faithfull
                  wrote on last edited by
                  #8

                  Believe it or not that's what I would expect. Remember that C# has its roots in C++ and in C++ everything can be validly initialised with a 0. It's an odd rule and one that seldom gets mentioned but we actually make a deal of use it to do things like initializing structures with {0} apart from every null initialised pointer prior to C++11's nullptr constant, which evaluates to, you guessed it, 0. In C++ Enums have no choice but to participate so enum types can also always be initialised with 0. It's so rare for enums not to have a zero valued member and for it to be an issue that I've never even considered what happens when an Enum with no zero valued member is initialised with 0 but I would expect it to 'work' in the sense of not raising more than a minor warning and to run and for the variable to have the value 0.

                  "The secret of happiness is freedom, and the secret of freedom, courage." Thucydides (B.C. 460-400)

                  L 1 Reply Last reply
                  0
                  • A AspDotNetDev

                    According to this, zero is basically the enum version of a default/null value. Not that it makes any more sense, but that seems to be the reason they allow for zero as a value for enums.

                    Thou mewling ill-breeding pignut!

                    L Offline
                    L Offline
                    lewax00
                    wrote on last edited by
                    #9

                    My problem with that treatment is that I might already be using 0 (and in most cases, I am, because I don't explicitly assign values if it isn't flags, and the first one will always be 0), and while I often declare a null-ish value in enums, there are plenty of cases where that also doesn't make sense. Something more explicit like "Enum.Null" would be fine, then it could be it's own type that's explicitly convertible to enum.

                    1 Reply Last reply
                    0
                    • M Matthew Faithfull

                      Believe it or not that's what I would expect. Remember that C# has its roots in C++ and in C++ everything can be validly initialised with a 0. It's an odd rule and one that seldom gets mentioned but we actually make a deal of use it to do things like initializing structures with {0} apart from every null initialised pointer prior to C++11's nullptr constant, which evaluates to, you guessed it, 0. In C++ Enums have no choice but to participate so enum types can also always be initialised with 0. It's so rare for enums not to have a zero valued member and for it to be an issue that I've never even considered what happens when an Enum with no zero valued member is initialised with 0 but I would expect it to 'work' in the sense of not raising more than a minor warning and to run and for the variable to have the value 0.

                      "The secret of happiness is freedom, and the secret of freedom, courage." Thucydides (B.C. 460-400)

                      L Offline
                      L Offline
                      lewax00
                      wrote on last edited by
                      #10

                      But in C++ (if I remember correctly), all integer types are implicitly convertible to enum. Then 0 assignment becomes expected behavior. In a language that explicitly prevents this, having one magic value that works does not make sense to me. Edit: Also, it doesn't work for other classes or structs either, so why should enum be special?

                      M 1 Reply Last reply
                      0
                      • A AspDotNetDev

                        According to this, zero is basically the enum version of a default/null value. Not that it makes any more sense, but that seems to be the reason they allow for zero as a value for enums.

                        Thou mewling ill-breeding pignut!

                        P Offline
                        P Offline
                        PIEBALDconsult
                        wrote on last edited by
                        #11

                        Having had a year to ponder it I suspect it's related to default, as in default(T) in a generic class. When T is an enumeration type the compiler has to get the default for the underlying type and that then has to be cast to the enumeration type -- but why the compiler can't use an explicit cast I don't know -- laziness I suspect. :sigh:

                        1 Reply Last reply
                        0
                        • L lewax00

                          But in C++ (if I remember correctly), all integer types are implicitly convertible to enum. Then 0 assignment becomes expected behavior. In a language that explicitly prevents this, having one magic value that works does not make sense to me. Edit: Also, it doesn't work for other classes or structs either, so why should enum be special?

                          M Offline
                          M Offline
                          Matthew Faithfull
                          wrote on last edited by
                          #12

                          I agree it doesn't make any sense in C# but my guess is its a hangover from C++ that still hasn't quite gone away rather than a deliberate design decision.

                          "The secret of happiness is freedom, and the secret of freedom, courage." Thucydides (B.C. 460-400)

                          L 1 Reply Last reply
                          0
                          • M Matthew Faithfull

                            I agree it doesn't make any sense in C# but my guess is its a hangover from C++ that still hasn't quite gone away rather than a deliberate design decision.

                            "The secret of happiness is freedom, and the secret of freedom, courage." Thucydides (B.C. 460-400)

                            L Offline
                            L Offline
                            lewax00
                            wrote on last edited by
                            #13

                            It seems hard to assume it wasn't, especially because it's not a feature of any other type (without implicit conversion explicitly defined...that's sounds kind of awkward). Kind of hard to end up with the one exception on accident. And of course, being Microsoft, with their huge love of never ever breaking compatibility unless there is no other way, even if it wasn't intentional, it's not likely to ever change now ("What if someone's code depends on it? Can't inconvenience those people using it on purpose!").

                            M 1 Reply Last reply
                            0
                            • L lewax00

                              It seems hard to assume it wasn't, especially because it's not a feature of any other type (without implicit conversion explicitly defined...that's sounds kind of awkward). Kind of hard to end up with the one exception on accident. And of course, being Microsoft, with their huge love of never ever breaking compatibility unless there is no other way, even if it wasn't intentional, it's not likely to ever change now ("What if someone's code depends on it? Can't inconvenience those people using it on purpose!").

                              M Offline
                              M Offline
                              Matthew Faithfull
                              wrote on last edited by
                              #14

                              lewax00 wrote:

                              it's not likely to ever change now

                              Very true. It's total speculation but I'd hazard it got in to C# in the first place due to being coded as a exceptional case in the C++ compiler being ported, sneaked through and got shipped and like much else that Microsoft has accidentally released not quite perfected, they were immediately stuck with it. I love their obsession with backward compatability after all how else would we have ended up with a Win32 API with 17 different functions for answering the question "How long is this piece of string going to be when I paint it on the screen?", with anything between 1 and 3 of them actually giving the correct answer depending on the version, the screen and the current alignment of Mars with the Moon. :laugh:

                              "The secret of happiness is freedom, and the secret of freedom, courage." Thucydides (B.C. 460-400)

                              1 Reply Last reply
                              0
                              • L lewax00

                                Part of an application I work on involves navigation through a series of documents, previously the navigate function looked like:

                                void NavigateTo(int document)

                                but as part of a redesign that made a single numeric index lose it's meaning, I changed it to

                                void NavigateTo(NavigationDirection direction)

                                where NavigationDirection is an enum consisting of Forward and Backward. As expected, the change caused some compilation errors where it was being called, because C# doesn't allow implicit conversion of int to enum. Having written the section of code it was in, I was pretty sure I knew where all the calls were, and the compiler seemed to agree...but the navigation was acting funny, it started at the second document. Debugged it, and found a third call to the function, that looked like this:

                                NavigateTo(0);

                                and 0 was the value of Forward, which was then moving it to the 2nd document, added a third value to the enum, None, since the first document was already being loaded in a new way, and this was just moving past it (the navigation has some side effects, loading other things related to the document, so the call was still needed...it makes more sense in the actual code, I'm just simplifying it). But hold on, I thought there wasn't an implicit conversion from int to enum types in C#? So I played around with it a bit, and here's what I discovered: ints are not implicitly convertible to enum types (as I thought)...but const ints are 0 is! Both integer literals, and const int variables, as long as the value maps to a value in the enum (if it had been a number greater than 1 other than 0, I would have had the expected compiler error). While I understand how the compiler can implement this, I don't understand why they would, it seems to go against the C# language itself. I don't think you could even write your own implicit conversion that behaves the same way, since from what I can tell C# doesn't generally make a distinction between const and non-const versions of the same type for the purposes of parameters (e.g. int and const int can be used interchangeably), with the exception of ref and out...but that causes restriction in the reverse direction (only non-const). Seems like an odd language design choice to me :doh: EDIT: looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

                                J Offline
                                J Offline
                                jschell
                                wrote on last edited by
                                #15

                                lewax00 wrote:

                                looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

                                However that isn't guaranteed. I have a test scenario where the MSMQ API would return an enumerated value (not zero) which was not in fact part of the enumeration. My supposition is that it is an unmanaged code conversion somewhere that wasn't accounted for.

                                L 1 Reply Last reply
                                0
                                • J jschell

                                  lewax00 wrote:

                                  looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

                                  However that isn't guaranteed. I have a test scenario where the MSMQ API would return an enumerated value (not zero) which was not in fact part of the enumeration. My supposition is that it is an unmanaged code conversion somewhere that wasn't accounted for.

                                  L Offline
                                  L Offline
                                  lewax00
                                  wrote on last edited by
                                  #16

                                  Well only 0 works at compile time anyways from what I can tell...guess I should assume switch statements using enums might actually receive other values too, and include a default case from now on, just in case, since the CLR clearly doesn't have an issue with passing other values as enums.

                                  1 Reply Last reply
                                  0
                                  • L lewax00

                                    There was something brought up there I didn't test...it is exclusive to 0. That is even worse. Even if I explicitly set the values of the enum so none of them are 0, 0 is still valid, but other ones are not even if they exist...but it gets worse. If there isn't one for 0, it just becomes the value 0 (which won't likely be handled by a function expecting a proper enum value), but if it does it becomes that enum value instead. Wat. :doh:

                                    M Offline
                                    M Offline
                                    Mike Winiberg
                                    wrote on last edited by
                                    #17

                                    I don't write in C#, (only C,C++, Java etc) but this strikes me as being very similar behaviour to early C/C++ compilers where 0 was acceptable as a NULL value for almost any pointer to any type of object. I wonder if that usage effectively crept through into C# in this particular case?

                                    1 Reply Last reply
                                    0
                                    • L lewax00

                                      Part of an application I work on involves navigation through a series of documents, previously the navigate function looked like:

                                      void NavigateTo(int document)

                                      but as part of a redesign that made a single numeric index lose it's meaning, I changed it to

                                      void NavigateTo(NavigationDirection direction)

                                      where NavigationDirection is an enum consisting of Forward and Backward. As expected, the change caused some compilation errors where it was being called, because C# doesn't allow implicit conversion of int to enum. Having written the section of code it was in, I was pretty sure I knew where all the calls were, and the compiler seemed to agree...but the navigation was acting funny, it started at the second document. Debugged it, and found a third call to the function, that looked like this:

                                      NavigateTo(0);

                                      and 0 was the value of Forward, which was then moving it to the 2nd document, added a third value to the enum, None, since the first document was already being loaded in a new way, and this was just moving past it (the navigation has some side effects, loading other things related to the document, so the call was still needed...it makes more sense in the actual code, I'm just simplifying it). But hold on, I thought there wasn't an implicit conversion from int to enum types in C#? So I played around with it a bit, and here's what I discovered: ints are not implicitly convertible to enum types (as I thought)...but const ints are 0 is! Both integer literals, and const int variables, as long as the value maps to a value in the enum (if it had been a number greater than 1 other than 0, I would have had the expected compiler error). While I understand how the compiler can implement this, I don't understand why they would, it seems to go against the C# language itself. I don't think you could even write your own implicit conversion that behaves the same way, since from what I can tell C# doesn't generally make a distinction between const and non-const versions of the same type for the purposes of parameters (e.g. int and const int can be used interchangeably), with the exception of ref and out...but that causes restriction in the reverse direction (only non-const). Seems like an odd language design choice to me :doh: EDIT: looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

                                      C Offline
                                      C Offline
                                      Cesar de Souza
                                      wrote on last edited by
                                      #18

                                      Interesting! I suppose this is one of the reasons for the existence of the CA1008 code analysis rule.

                                      Quote:

                                      CA1008: Enums should have zero value[^] Cause: An enumeration without an applied System.FlagsAttribute does not define a member that has a value of zero; or an enumeration that has an applied FlagsAttribute defines a member that has a value of zero but its name is not 'None', or the enumeration defines multiple zero-valued members.

                                      Perhaps by specifying a default value with a "no action" behavior it would have been easier to spot this one, or at least it wouldn't lead on the weird behavior (you would have to explicitly handle or ignore the .None values).

                                      Interested in Machine Learning in .NET? Check the Accord.NET Framework. See also Sequence Classifiers in C# with Hidden Conditional Random Fields.

                                      L 1 Reply Last reply
                                      0
                                      • L lewax00

                                        Part of an application I work on involves navigation through a series of documents, previously the navigate function looked like:

                                        void NavigateTo(int document)

                                        but as part of a redesign that made a single numeric index lose it's meaning, I changed it to

                                        void NavigateTo(NavigationDirection direction)

                                        where NavigationDirection is an enum consisting of Forward and Backward. As expected, the change caused some compilation errors where it was being called, because C# doesn't allow implicit conversion of int to enum. Having written the section of code it was in, I was pretty sure I knew where all the calls were, and the compiler seemed to agree...but the navigation was acting funny, it started at the second document. Debugged it, and found a third call to the function, that looked like this:

                                        NavigateTo(0);

                                        and 0 was the value of Forward, which was then moving it to the 2nd document, added a third value to the enum, None, since the first document was already being loaded in a new way, and this was just moving past it (the navigation has some side effects, loading other things related to the document, so the call was still needed...it makes more sense in the actual code, I'm just simplifying it). But hold on, I thought there wasn't an implicit conversion from int to enum types in C#? So I played around with it a bit, and here's what I discovered: ints are not implicitly convertible to enum types (as I thought)...but const ints are 0 is! Both integer literals, and const int variables, as long as the value maps to a value in the enum (if it had been a number greater than 1 other than 0, I would have had the expected compiler error). While I understand how the compiler can implement this, I don't understand why they would, it seems to go against the C# language itself. I don't think you could even write your own implicit conversion that behaves the same way, since from what I can tell C# doesn't generally make a distinction between const and non-const versions of the same type for the purposes of parameters (e.g. int and const int can be used interchangeably), with the exception of ref and out...but that causes restriction in the reverse direction (only non-const). Seems like an odd language design choice to me :doh: EDIT: looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

                                        E Offline
                                        E Offline
                                        englebart
                                        wrote on last edited by
                                        #19

                                        So it seems like in your case it would be safest to setup your enum like: {None=0, Forward=1, Backward=2} If you ever receive a None, you could email yourself a stacktrace. Also, include a default case with similar behavior.

                                        L 1 Reply Last reply
                                        0
                                        • L lewax00

                                          Part of an application I work on involves navigation through a series of documents, previously the navigate function looked like:

                                          void NavigateTo(int document)

                                          but as part of a redesign that made a single numeric index lose it's meaning, I changed it to

                                          void NavigateTo(NavigationDirection direction)

                                          where NavigationDirection is an enum consisting of Forward and Backward. As expected, the change caused some compilation errors where it was being called, because C# doesn't allow implicit conversion of int to enum. Having written the section of code it was in, I was pretty sure I knew where all the calls were, and the compiler seemed to agree...but the navigation was acting funny, it started at the second document. Debugged it, and found a third call to the function, that looked like this:

                                          NavigateTo(0);

                                          and 0 was the value of Forward, which was then moving it to the 2nd document, added a third value to the enum, None, since the first document was already being loaded in a new way, and this was just moving past it (the navigation has some side effects, loading other things related to the document, so the call was still needed...it makes more sense in the actual code, I'm just simplifying it). But hold on, I thought there wasn't an implicit conversion from int to enum types in C#? So I played around with it a bit, and here's what I discovered: ints are not implicitly convertible to enum types (as I thought)...but const ints are 0 is! Both integer literals, and const int variables, as long as the value maps to a value in the enum (if it had been a number greater than 1 other than 0, I would have had the expected compiler error). While I understand how the compiler can implement this, I don't understand why they would, it seems to go against the C# language itself. I don't think you could even write your own implicit conversion that behaves the same way, since from what I can tell C# doesn't generally make a distinction between const and non-const versions of the same type for the purposes of parameters (e.g. int and const int can be used interchangeably), with the exception of ref and out...but that causes restriction in the reverse direction (only non-const). Seems like an odd language design choice to me :doh: EDIT: looks like I jumped the gun a little on this one, apparently, it only works for 0. Which is probably worse...

                                          R Offline
                                          R Offline
                                          RafagaX
                                          wrote on last edited by
                                          #20

                                          Well as some people say, if it's not a bug, it's a feature... ;P

                                          CEO at: - Rafaga Systems - Para Facturas - Modern Components for the moment...

                                          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