Is everything in .NET an object?
Please help us settle the controversy of "Nearly" everything is an object (an answer to Stack Overflow question As a novice, is there anything I should beware of before learning C#?). I thought that was the case as everything in Visual Studio at least appears as a struct. Please post a reference, so that it doesn't become "modern jackass" (This American Life).
Note that this question refers to C#, not necessarily .NET, and how it handles the data under the hood (obviously it's all 1's and 0's).
Here are the comments to "everything is an object":
- Eh, no, it's not. – Binary Worrier
- I'd like an example... – scotty2012
- isn't everything derived from the base type Object? – rizzle
- Most things are objects... – Omar Kooheji
- Value types, ints, doubles, object references (not the objects them selves) etc aren't objects. They can be "boxed" to look like objects (e.g. i.ToString()) but really they're primitive types. Change the entry to "NEARLY everthing is an object" and I'll remove the downvote – Binary Worrier
- I appreciate the clarification. I think the lowest level that you can interact with, say an int, in C# is as a struct, which isn't an object? - http://msdn.microsoft.com/en-us/library/ms173109.aspx – rizzle
- Doesn't Int32 inherit from ValueType which inherits from Object? If so, despite the behavior, an int is an object. – Chris Farmer
- No, the boxed type for int inherits from ValueType, which inherits from Object. They're not objects in the traditional sense because a) an int isn't a reference to an int, IT IS the int. b) ints aren't garbage collected. If you declare an Int32, then that int is 4 bytes on the stack, end of story – Binary Worrier
Definition of object: "Object" as a inheritor of class System.Object vs. "object" as an instance of a type vs. "object" as a reference type."
The problem here is that this is really two questions - one question is about inheritance, in which case the answer is "nearly everything", and the other is about reference type vs value type/memory/boxing, which case the answer is "no".
Inheritance:
In C#, the following is true:
- All value types, including enums and nullable types, are derived from
System.Object
. - All class, array, and delegate types are derived from
System.Object
. - Interface types are not derived from
System.Object
. They are all convertible toSystem.Object
, but interfaces only derive from other interface types, andSystem.Object
is not an interface type. - No pointer types derive from
System.Object
, nor are any of them directly convertible toSystem.Object
. - "Open" type parameter types are also not derived from
System.Object
. Type parameter types are not derived from anything; type arguments are constrained to be derived from the effective base class, but they themselves are not "derived" from anything.
From the MSDN entry for System.Object:
Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.
Languages typically do not require a class to declare inheritance from Object because the inheritance is implicit.
Because all classes in the .NET Framework are derived from Object, every method defined in the Object class is available in all objects in the system. Derived classes can and do override some of these methods.
So not every type in C# is derived from System.Object
. And even for those types that are, you still need to note the difference between reference types and value types, as they are treated very differently.
Boxing:
While value types do inherit from System.Object
, they are treated differently in memory from reference types, and the semantics of how they are passed through methods in your code are different as well. Indeed, a value type is not treated as an Object (a reference type), until you explicitly instruct your application to do so by boxing it as a reference type. See more information about boxing in C# here.
A little late to the party, but I came across this in a search result on SO and figured the link below would help future generations:
Eric Lippert discusses this very thoroughly, with a much better (qualified) statement:
The way to correct this myth is to simply replace "derives from" with "is convertible to", and to ignore pointer types: every non-pointer type in C# is convertible to object.
The gist of it, if you hate reading well-illustrated explanations from people that write programming languages, is that (pointers aside), things like Interface, or generic parameter type declarations ("T") are not objects, but are guaranteed to be treatable as objects at runtime, because they have a definite instance, that will be an Object. Other types (Type, Enum, Delegate, classes, etc.) are all Objects. Including value types, which can be boxed to object as other answers have discussed.