Is everything in .NET an object?

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 to System.Object, but interfaces only derive from other interface types, and System.Object is not an interface type.
  • No pointer types derive from System.Object, nor are any of them directly convertible to System.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.


Some people here have a strange notion of what an “object” in object-oriented programming is. In order for something to be an object it does not have to be a reference type or, more generally, follow any formal implementation.

All that means is that you can operate on it as a first-class citizen in an object-oriented world. Since you can do this on values in C# (thanks to autoboxing), everything is indeed an object. To some extend, this is even true for functions (but arguably not for classes).

Whether this is relevant in practice is another question but this is a general problem with OOP that I notice once again. Nobody is clear on the definition of OOP (yes, most people agree that it has something to do with polymorphism, inheritance and encapsulation, some throw in “abstraction” for good measure).

From a usage point of view, every value in C# handles like an object. That said, I like the currently accepted answer. It offers both technically important aspects.

Notice that in other contexts, e.g. C++, other aspects are stressed since C++ isn't necessarily object-oriented and furthermore is much more focused on low-level aspects. Therefore, the distinction between objects, POD and builtin primitives makes sometimes sense (then again, sometimes not).

Tags:

C#

Object