Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

C# Programming Question

Name: Anonymous 2010-10-21 14:24

object a = 10;
object b = 10;
object c = "10";
object d = "10";

Console.WriteLine(a == b); // false
Console.WriteLine(c == d); // true

why does the "Console.WriteLine(a == b)" outputs "false"?

Name: Anonymous 2010-10-21 14:28

Because the cook is mayor's nephew.

Name: Anonymous 2010-10-21 14:38

because coctothorpe is jew

Name: VIPPER 2010-10-21 15:07

SNAKES

Name: Anonymous 2010-10-21 15:18

>>4
That was VIP quality!

Name: Anonymous 2010-10-21 15:53

I know about this. It has something to do with packing, nomads and/or tail recursion.

Name: Anonymous 2010-10-21 16:20

>>1
Console.WriteLine(a == b); // false
Console.WriteLine(a.Equals(b)); // true                                       
/* For arguments of value type, the operator == returns true if its            
   operands have the same value, false otherwise. For the string type,         
   it returns true if the strings' character sequences match. For other        
   reference types (types derived from System.Object), however, a == b         
   returns true only if a and b reference the same object. */

Name: Anonymous 2010-10-21 16:23

Console.WriteLine(3.Equals(3f)); // false
Console.WriteLine(3f.Equals(3)); // true

Name: Anonymous 2010-10-21 16:45

>>7
a.Equals(b)
ohgod the pain

Name: Anonymous 2010-10-21 17:27

>>1
Now try it with object d = "1"; d += "0";. It's false again!

First you need to understand the difference between value types and reference types.

Value types are: int, double, char, TimeSpan etc plus user-defined structures.

Reference types are: string, object, plus all user-defined objects.

The variable of a value type holds the value itself. The value of a reference type holds a reference to a value allocated somewhere else. When you declare an int field in an object, it names the four bytes withing that object where the value is stored, or the four bytes on the stack for a local variable inside a function. When you declare a string field or variable, that variable names a four or eight bytes of a pointer, that holds an address of the actual value of the string which is stored somewhere else.

The primary difference is that when you write "a = b", if both are value types then the value of the `b` variable is copied into the `a` variable and now you have two separate copies of the value. If both are reference types, then the reference is copied, and now both point at the same value.

You shouldn't confuse that with immutability, which is an orthogonal concept. I mean, the litmus test to determine what we are dealing with, two separate but equal values or two variables pointing at the same value, is to modify the value of the variable `a` and see if the value of `b` changes. But if `a` and `b` are strings you can't do that, strings are immutable, when you write `a += b` it actually means `a = a + b` -- i.e. a new string object is created and its address is stored in `a`.

Then. When you assign a value of a value type (such as an integer) to a variable of compatible reference type (such as System.Object, other variants include user-defined structures that implement some interface, and a variable of that interface type) then the magical autoboxing happens: an new value is created on the heap and the variable is assigned a reference to that value. The name means that a "box" object is created and the value is stored inside it, automatically.

Note that while the value of plain int takes 4 bytes, the object that holds that value after boxing is rather huge -- it contains a pointer to its class (System.Int32) among other things. Also note that a boxed int is immutable too!

Then. The operators like `==` are resolved at compile time, based on the types of the variables involved, not of the objects that the variables (if they are of reference types) are referencing. Which means that if you compare two variables of type int, then int's comparison operator is invoked, and it compares values. When you compare two variables of type string, then string's comparison operator is invoked, and it goes through references and again compares values.

But when you compare two variables of type object, then object's comparison operator is invoked, and it compares references themselves. Which are different in case of two boxed ints. But which are the same in case of two _constant_ strings -- the compiler notices that the values are the same (even if you write it as "1" + "0"), stores the single value which is then referenced by both your variables. And which are again different if you create a new string with the same value at runtime.

Finally, the last puzzling question is, how the fuck `c += "0"` works if `c` is an object? Well, first, compiler transforms that into `c = c + "0"`. Then it sees that System.String (the constant "0") happens to define an addition operator with an object on the left side (which calls its .ToString()). The call to which it happily compiles then.

Your welcome!

Name: Anonymous 2010-10-21 17:34

Oh look, another "object oriented" language, where actually, not everything is an object.
It's a shame you can't have operator== like in my favourite language, C++.

Name: >>10 2010-10-21 17:37

>>7
Wrong, that is, not directly related to the problem at hand.

>>8
Seems scary, but what are the options really? Forbid the integer promotion to float, so that both evaluate to false? That would have other consequences that would suck. Somehow sneak in a comparison with an integer into the float's Equals? I dunno, that kinda sucks too, for architectural reasons. We don't have a numeric tower in C#, but if we had, that would be a wrong thing to do.

>>9
It's not Java, just don't use boxed integers without unboxing them first and you'll never have to call Equals, ever. I know, I never had to, like, literally never.

Name: Anonymous 2010-10-21 17:38

>>11
In C# everything is an object.

You can have operator== in C#.

Shut your fucking ignorant American fat face up.

Name: Anonymous 2010-10-21 17:47

>>11
IHBT In C++, not everything is an object.  A rough (and partially incorrect) estimation says that in C++, everything is either a POD (scalars, pointers, structs) or an object (class instance).  In C++ you can't have a reference type that can hold a reference to any other type (void* doesn't work).  In C#, you can cast anything to "object" and then cast it back.  Value types get boxed -- a tradeoff that makes it easier to store the value types on the stack in the first place.

In C#, "==" will work as expected when you're working with variables that are typed, just like C++.  It will compare references when you give it operands of type "object", which isn't something you can do in C++ anyway.

So really, C++ is the language where you can't cast everything to "object", both Java and C# allow this.  (This really has nothing at all to do with object-oriented programming, and everything to do with dynamic type systems, which was kind of stapled onto C++ and doesn't go "all the way down".)

Name: Anonymous 2010-10-21 18:04

>>13,14
Wow. /prog/ is officially no longer a Lisp board.

Name: Anonymous 2010-10-21 18:47

>>15
what the hell is lisp?

Name: Anonymous 2010-10-21 19:07

Name: Anonymous 2010-10-22 3:17

>>17
wow this board is really gay

Name: Anonymous 2010-10-22 3:55

>>18
I know, thats why we talk about anus all the time

Name: Anonymous 2010-10-22 4:03

>>10

marry me

Don't change these.
Name: Email:
Entire Thread Thread List