1

I wrote this code in C#:

public static double method ()
{ 
    return 1.3;
}

public static Boolean methodO(object o)
{ 
    return o.Equals(1.3);
}

public static void Main()
{
    System.Console.WriteLine(methodO(method())); // prints 'true'
}

Why does this compile?

Is this because "everything in C# is an object", and so even if it's a primitive type it's an object too and so it implements the "Equals" method?

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
justHelloWorld
  • 6,478
  • 8
  • 58
  • 138
  • Possible duplicate of [What is the default behavior of Equals Method?](http://stackoverflow.com/questions/2632369/what-is-the-default-behavior-of-equals-method) if I understand the question correctly. – CodeCaster Feb 04 '15 at 20:32
  • I mean "how is it possible that a value type can be used as an object argument of a method"? – justHelloWorld Feb 04 '15 at 20:34
  • 3
    [Because everything's an object](http://stackoverflow.com/questions/1682231/how-do-valuetypes-derive-from-object-referencetype-and-still-be-valuetypes) [(well, not everything)](http://blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx). – CodeCaster Feb 04 '15 at 20:34
  • 1
    possible duplicate of [Why do we need boxing and unboxing in C#?](http://stackoverflow.com/questions/2111857/why-do-we-need-boxing-and-unboxing-in-c) – Philip Pittle Feb 04 '15 at 20:46
  • 2
    My suggestions for you are that (1) you banish the notion of "primitive type" from your mind; this is not a concept that is needed in C#, and (2) stop considering the ontological question "*is a double an object?*" The correct question to consider is the question "*can an expression of type double be implicitly converted to type object?*" The answer to that question is clearly yes; this is classified as an *implicit boxing conversion* by the specification. – Eric Lippert Feb 04 '15 at 21:53

1 Answers1

3

The reason you can pass a value type (double, int, etc) to a method that is expecting an object is .Net will automatically convert the value type to an object. This process is called boxing and you can read more about it on MSDN: https://msdn.microsoft.com/en-us/library/yz2be5wk.aspx

Another way to think about this, is this code is perfectly valid:

int i = 5;
object o = i; //box i into an object
int y = (int)o;  //unbox o into an int

You should also be aware that there is a performance penalty for doing this.

Philip Pittle
  • 11,821
  • 8
  • 59
  • 123
  • 2
    While what you said is true, it's not actually the reason why it can be passed to a function with an object parameter. The boxing is done for referencing, but the reason that compiles is because `System.Double` is a struct, which inherits from `System.ValueType`, which inherits from `System.Object` (or its alias `object`), so it's just a valid object to pass to a function expecting an `object`. – Jcl Feb 04 '15 at 20:45
  • Another perspective: double inherits from object; which means every double is object too. – Mustafa Chelik Feb 04 '15 at 21:40
  • 1
    @Jcl: You do not need to resort to this complicated argument. Section 4.3.1 of the specification says that a boxing conversion exists "from any value type to object". There is no need to go from the value type to `ValueType` and then make a reference conversion to object. – Eric Lippert Feb 04 '15 at 21:59
  • The performance is because we generate an object of type double at run-time, which will be allocated on the heap, is that right? Another little question: if I code `int x = 5; x.ToString()` a boxing is implicitly done or not? – justHelloWorld Feb 04 '15 at 22:42
  • @EricLippert oh, I was not implying that... I just meant that `double` was an `object` and just stating the inheritance chain. – Jcl Feb 05 '15 at 06:12
  • 2
    @justHelloWorld: The answer to your first question is "yes" and the answer to your second question is "no", but I would encourage you to *post a new question when you have a question*. That's what this site is for! – Eric Lippert Feb 05 '15 at 14:30