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. dotNET Rant [modified]

dotNET Rant [modified]

Scheduled Pinned Locked Moved The Lounge
questioncsharpcomlearning
101 Posts 25 Posters 11 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.
  • T TheGreatAndPowerfulOz

    That's an interesting oddity, to be sure. I don't see why the second case is not boxing. Isn't any literal integer a value type by definition? So then, if the two examples are different, then what is boxed in the first case? A reference to the iOne, iTwo variables? Or are their respective values boxed? And then what is the second case called, if not boxed? Consider the following code.

    void func(out object one, out object two)
    {
    int iOne = 1;
    one = iOne;

    two = 2;
    

    }

    what is in 'one' and what is in 'two' after the return of this function? I submit they're both boxed. Of course, I admit I'm no expert and I'm fully ready to be instructed.

    Fight Big Government:
    http://obamacareclassaction.com/
    http://obamacaretruth.org/

    B Offline
    B Offline
    Brady Kelly
    wrote on last edited by
    #87

    In Scott's first case, a new Int32 object is created with a value. Assigning this object to another object causes boxing, because the RHS value type is not 'compatible' with the LHS ref type. In his second case, object one = 1;, once again a new Int32 object is created, but I assume that because it was created 'right there', buy the CLR, it can be directly assigned to the RHS. How far off the mark am I guys?

    S T 2 Replies Last reply
    0
    • T TheGreatAndPowerfulOz

      but in code that is comparing boxed values, you don't know what the boxed types are so it's not as simple as casting to a known type.

      Fight Big Government:
      http://obamacareclassaction.com/
      http://obamacaretruth.org/

      B Offline
      B Offline
      Brady Kelly
      wrote on last edited by
      #88

      ahmed zahmed wrote:

      you don't know what the boxed types

      I think that is a key point, and maybe why '==' doesn't attempt a value comparison.

      1 Reply Last reply
      0
      • T TheGreatAndPowerfulOz

        Well, it seems that it would given my remembered(and corrected/reminded) understanding. So 'same' would be false. (Haven't typed it into a compiler yet so I don't really 'know' -- lol). In any case, my rant was incorrectly focused. I was really venting about a larger issue and focused on this one small thing. Still, looking at it from a novice perspective (which I'm not -- even though it sure sounded like it yesterday --, but it helps sometimes to do that), it seems incongruous to have the result it does. Of course, once explained to said novice, it's understood. It's just programming after all, and each language/runtime has its 'quirks'. cheers.

        Fight Big Government:
        http://obamacareclassaction.com/
        http://obamacaretruth.org/

        B Offline
        B Offline
        Brady Kelly
        wrote on last edited by
        #89

        ahmed zahmed wrote:

        Still, looking at it from a novice perspective (which I'm not -- even though it sure sounded like it yesterday --, but it helps sometimes to do that), it seems incongruous to have the result it does.

        I suspect the same of the C# interpretation of the Laws for the pre- and post-decrement operators. I'll remember and post the experiment a bit later.

        1 Reply Last reply
        0
        • T Tim Yen

          I dont think there is a reason, just a coin toss. Because everything inherits from object it might be easier to compare the pointer values. But they could just as easily have done a ToString() on each object and compared values. Maybe its to deal with null references, where ToString() would not work? But then they could always have had some pre defined rule as when two null references are compared they are equal, like if both null then they are equal otherwise false

          B Offline
          B Offline
          Brady Kelly
          wrote on last edited by
          #90

          Tim Yen wrote:

          Maybe its to deal with null references, where ToString() would not work?

          Aha! My morning is complete, and the nagging question of why they don't just call Equals() on both objects is answered.

          1 Reply Last reply
          0
          • D Daniel Grunwald

            Because keeping all 2^32 possible integers around until they are (maybe) reused would waste up to 48 GB of RAM (or 96 GB on 64-bit systems, as the overhead of objects is higher there). And I don't really want the Java behavior where all integers between -128 and 127 return the same object, but all other integers don't.

            C Offline
            C Offline
            CurtainDog
            wrote on last edited by
            #91

            Fair call, I must admit I was mostly thinking of literals when I made my comment. These of course would be able to be handled at compile time.

            1 Reply Last reply
            0
            • E englebart

              This is because dotNET is Microsoft's version of Java, and that is how Java would do it. My guess is that you are coming from a C++ background where you expect it to call operator==(). The main difference between Java and the first dotNET was that Java lowercased the first letter of methods, while dotNET uppercased the first letter. dotNET has evolved at a much faster (almost unstable) pace since then. Disclosure: I am a Java programmer that is glad that MS created dotNET. Java would probably still not have enums if MS hadn't ditched Java and started competing directly against it.

              C Offline
              C Offline
              CurtainDog
              wrote on last edited by
              #92

              .Net is the platform and C# is the language; in the Javaverse they're both called Java, which is highly confusing. As pointed out in one of the responses above the original code would behave differently in Java because Java caches Integer 0. I'm also a Java programmer and with the exception of generics I'm ambivalent about the language changes in 1.5 & 1.6

              1 Reply Last reply
              0
              • T TheGreatAndPowerfulOz

                I dont think he was complaining about the 'ref' keyword, but rather the way == is overloaded on object to mean "compare" pointers. But, then when all you have is an 'object' what else can you do? Still it seems that the runtime knows that it's a boxed value-type and could do something 'smarter'. But I don't know the full implications of doing something like that, at least not now. Who knows what would break.

                Fight Big Government:
                http://obamacareclassaction.com/
                http://obamacaretruth.org/

                T Offline
                T Offline
                Tim Yen
                wrote on last edited by
                #93

                Yes I wasn't saying the ref keyword didn't serve some purpose in the language as it is now, I was really leading to the fact that the designers of C# invented the ref keyword to deal with a particular problem and therefore they could have invented another way of making the == operator unambiguous. I imagine they could have invented a complex set of rules to avoid the keyword ref and potentially made the language more ambiguous which is what they have done with ==. Or they could have gone down the path of avoiding the overload. I think the language features are now cast in stone and it will take the next version of C# (maybe C##) to fix the silly bits.

                1 Reply Last reply
                0
                • S Sam Meacham

                  What makes you think that a == b and a.Equals(b) should be the same? They are by definition different, and specifically used to check different things, both of which are necessary. Reference equals (the == operator, or the more explicit Object.ReferenceEquals method) checks to see if two variables (or pointers, since you are dealing with reference types) point to the same object in memory, e.g., do they have the same address. Using a.Equals(b) is the same as Object.Equals(a, b), and it compares the values of the two objects. This is very well defined behavior, and most programming languages discern the difference between reference and value comparison. Just because you have not understood the problem, or better yet, the solution to the problem, does not mean that it is a design flaw. To assert that it is a design flaw it to also assert that you have a complete understanding of the language and the specification, and clearly, you do not.

                  T Offline
                  T Offline
                  Tim Yen
                  wrote on last edited by
                  #94

                  hang on

                  Sam Meacham wrote:

                  Using a.Equals(b) is the same as Object.Equals(a, b), and it compares the values of the two objects.

                  No it doesn't. http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx[^] "The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types" I don't think he has misunderstood the problem, I think you have misunderstood the original rant. The original rant is about they way equals works and him disagreeing with the way it works. He believes == should always do a value comparison and there should be some other way like ReferenceEquals() to do a reference comparison. I agree with him. The way == works now you have to know the type of the variables and then apply the rules. But the rules even then aren't 100% consistent, in the strange case of the string object == does a value comparison but all other objects it does a reference comparison. With the addition of the var keyword this type knowledge may not be available within the current function and possibly the current class or even current project. It may only be available in a referenced library. So you may not have access to the code and as such the type information until run time to do an == on a variable. After thinking about this for a while I think the reason they went down the current path is value comparison of two objects would require evaluating all branches of the object, which may be computationally expensive and potentially very expensive if your comparing say a list of lists of lists of objects. Still there could be other ways around this by generating compiler errors on "object == object" and developing other syntax like object.ReferenceEquals(object)

                  1 Reply Last reply
                  0
                  • B Brady Kelly

                    In Scott's first case, a new Int32 object is created with a value. Assigning this object to another object causes boxing, because the RHS value type is not 'compatible' with the LHS ref type. In his second case, object one = 1;, once again a new Int32 object is created, but I assume that because it was created 'right there', buy the CLR, it can be directly assigned to the RHS. How far off the mark am I guys?

                    S Offline
                    S Offline
                    Scott Dorman
                    wrote on last edited by
                    #95

                    Yes, that's pretty much correct.

                    Scott Dorman

                    Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                    Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                    1 Reply Last reply
                    0
                    • T TheGreatAndPowerfulOz

                      That's an interesting oddity, to be sure. I don't see why the second case is not boxing. Isn't any literal integer a value type by definition? So then, if the two examples are different, then what is boxed in the first case? A reference to the iOne, iTwo variables? Or are their respective values boxed? And then what is the second case called, if not boxed? Consider the following code.

                      void func(out object one, out object two)
                      {
                      int iOne = 1;
                      one = iOne;

                      two = 2;
                      

                      }

                      what is in 'one' and what is in 'two' after the return of this function? I submit they're both boxed. Of course, I admit I'm no expert and I'm fully ready to be instructed.

                      Fight Big Government:
                      http://obamacareclassaction.com/
                      http://obamacaretruth.org/

                      S Offline
                      S Offline
                      Scott Dorman
                      wrote on last edited by
                      #96

                      The second case is not boxing because you are assigning a literal value to the object. A literal value essentially takes on the type of the object to which it is assigned (not the real implementation details, but it should get the idea across). That would mean that a literal integer value is only a value type if it is assigned to a value type. In the second example, the literal values are assigned to object variables, so no boxing occurs. Any time a boxing operation occurs, the value of the value type being boxed is copied into the reference type. As for what the second case is called, there isn't a name since there is no boxing or unboxing operations. It is simply variable assignment. In your func example, you have a function with two out object parameters. In the body of the function, you are essentially doing two things:

                      1. You create an int value type and then assign it to an object argument. This is a boxing operation.
                      2. You assign a literal value 2 to an object argument. Since you are assigning a literal value, this is not a boxing operation.

                      Scott Dorman

                      Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                      Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                      T 1 Reply Last reply
                      0
                      • S Scott Dorman

                        The second case is not boxing because you are assigning a literal value to the object. A literal value essentially takes on the type of the object to which it is assigned (not the real implementation details, but it should get the idea across). That would mean that a literal integer value is only a value type if it is assigned to a value type. In the second example, the literal values are assigned to object variables, so no boxing occurs. Any time a boxing operation occurs, the value of the value type being boxed is copied into the reference type. As for what the second case is called, there isn't a name since there is no boxing or unboxing operations. It is simply variable assignment. In your func example, you have a function with two out object parameters. In the body of the function, you are essentially doing two things:

                        1. You create an int value type and then assign it to an object argument. This is a boxing operation.
                        2. You assign a literal value 2 to an object argument. Since you are assigning a literal value, this is not a boxing operation.

                        Scott Dorman

                        Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                        Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                        T Offline
                        T Offline
                        TheGreatAndPowerfulOz
                        wrote on last edited by
                        #97

                        Thanks, Scott. That's very enlightening. Now I understand. Don't know why there should be a distinction in these cases, but what you're saying makes sense.

                        Fight Big Government:
                        http://obamacareclassaction.com/
                        http://obamacaretruth.org/

                        1 Reply Last reply
                        0
                        • B Brady Kelly

                          In Scott's first case, a new Int32 object is created with a value. Assigning this object to another object causes boxing, because the RHS value type is not 'compatible' with the LHS ref type. In his second case, object one = 1;, once again a new Int32 object is created, but I assume that because it was created 'right there', buy the CLR, it can be directly assigned to the RHS. How far off the mark am I guys?

                          T Offline
                          T Offline
                          TheGreatAndPowerfulOz
                          wrote on last edited by
                          #98

                          Thanks Brady, yours and Scott's explanation helped a lot.

                          Fight Big Government:
                          http://obamacareclassaction.com/
                          http://obamacaretruth.org/

                          1 Reply Last reply
                          0
                          • S Sam Meacham

                            What makes you think that a == b and a.Equals(b) should be the same? They are by definition different, and specifically used to check different things, both of which are necessary. Reference equals (the == operator, or the more explicit Object.ReferenceEquals method) checks to see if two variables (or pointers, since you are dealing with reference types) point to the same object in memory, e.g., do they have the same address. Using a.Equals(b) is the same as Object.Equals(a, b), and it compares the values of the two objects. This is very well defined behavior, and most programming languages discern the difference between reference and value comparison. Just because you have not understood the problem, or better yet, the solution to the problem, does not mean that it is a design flaw. To assert that it is a design flaw it to also assert that you have a complete understanding of the language and the specification, and clearly, you do not.

                            T Offline
                            T Offline
                            TheGreatAndPowerfulOz
                            wrote on last edited by
                            #99

                            That's exactly my point. I'm disagreeing with the "by definition" they are different part. Yes, by definition they are different. But, by reading comprehension and mathematical definition they should be semantically the same. Semantics should *always* override ease of the runtime or compiler. Make the code easy to understand and read and there will be less errors. Reference comparison should be the odd-man out and should be called-out by a specific operator or method call. So yes, I think it a design flaw. Just my humble opinion. And one does not have to understand or know the entire design to see a flaw in one area. The current design in this one spot strikes me as a hack.

                            Fight Big Government:
                            http://obamacareclassaction.com/
                            http://obamacaretruth.org/

                            S 1 Reply Last reply
                            0
                            • T TheGreatAndPowerfulOz

                              That's exactly my point. I'm disagreeing with the "by definition" they are different part. Yes, by definition they are different. But, by reading comprehension and mathematical definition they should be semantically the same. Semantics should *always* override ease of the runtime or compiler. Make the code easy to understand and read and there will be less errors. Reference comparison should be the odd-man out and should be called-out by a specific operator or method call. So yes, I think it a design flaw. Just my humble opinion. And one does not have to understand or know the entire design to see a flaw in one area. The current design in this one spot strikes me as a hack.

                              Fight Big Government:
                              http://obamacareclassaction.com/
                              http://obamacaretruth.org/

                              S Offline
                              S Offline
                              Sam Meacham
                              wrote on last edited by
                              #100

                              Fair enough, and well stated. I'm glad you made your original rant in the first place anyway, because as Tim Yen pointed out, I was incorrect about what types of equality checks were used in certain situations anyway. I was wrong, and now that I've been corrected, I'm a little smarter for it (thanks Tim). I am tending to agree with you now, that it would be better if there were simply two explicit checks. A non-overloadable reference-equals check, and an overloadable value-equals check.

                              1 Reply Last reply
                              0
                              • T TheGreatAndPowerfulOz

                                ok, this is not a programming question. It's a rant! given,

                                object one = 0;
                                object two = 0;
                                bool same = one == two;

                                what would you expect the value of same to be? WRONG! it's false! Whoever thought that was a valid result, is cracked!:mad::mad::mad::mad::mad: [edit] so, after going home and resting my brain a bit. it seems as though i'm the one that was cracked. thanks for the refresher course everyone. it is of course doing a reference comparison. which is correct. you all know how it is when you struggle with something and get too close to the trees to see the forest. anyway thanks to everyone for being your normally brutally honest selves. cheers. :-D [/edit]

                                Fight Big Government:
                                http://obamacareclassaction.com/
                                http://obamacaretruth.org/

                                modified on Friday, May 7, 2010 1:08 AM

                                G Offline
                                G Offline
                                Grant BlahaErath
                                wrote on last edited by
                                #101

                                ahmed zahmed ranted about == not measuring underlying boxed types in: http://www.codeproject.com/Lounge.aspx?msg=3464288#xx3464288xx
                                The mechanism is explained in the thread, but the more interesting question is why Hejlsberg et al. would design the language this way. Certainly, there are other languages that just bundle value and reference comparison into one operator. My first guess would be performance since it could be costly to have the compiler generate reflection checks to see if every object was an underlying boxed value type. The other thought is that comparison operators are always static (and can't polymorph). Again, that makes sense from a performance perspective as well since there would be no need to deref to a jump table for every == operation. Since there are some great scenarios for polymorphing comparison, there is the .Equals on every object. More overhead, but the choice to use the abstraction is in the hands of the coder. There are also languages that only do this (and hence stuff == into some kind of table). Anyone see any other reason than performance? Maybe 'cause Java did it? :-)

                                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