Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Microsoft make all .NET classes implicitly inherit from the Object class? Can I do the same kind of thing?

All classes that we create inherit from the Object class without needing to explicitly declare inheritance to that class.

  • How does Microsoft can make all .NET class implicitly inherit from the Object class?
  • Does the compiler inject that inheritance behind the scenes?
  • Can I do the same kind of thing: make all my classes inherit implicitly from a class interface for example?

My question may be ambiguous so I will clarify:

I'm not asking about inheriting from another class other than Object since I know that multiple inheritance for classes is forbidden. I'm talking about inheritance rather through class Interfaces, my question is about IMPLICITLY DOING IT not about substituting an object by another class of my own, or do multiple inheritance with Object and another class of my own. I want to get all classes inherit form Interface1OfMyOwn and Interface2OfMyOwn.

like image 912
user310291 Avatar asked Nov 30 '22 13:11

user310291


2 Answers

All classes implicitly extend Object because the C# standard specifies the language so.

Asking how they implemented that is like asking how they implemented the fact that a void method doesn't return data, or how they implemented the fact that classes have properties: It's simply somewhere in the code of the compiler (which here may be the C# compiler or the JIT compiler). We can't know for sure, but it's plausible to say that whenever the compiler doesn't detect explicit inheritance in a class, it just goes for System.Object instead, simple as that. So you'll have to accept that Object is simply a special type for the compiler.

Why you can't do that with a custom class seems obvious: It would thoroughly confuse the compiler over whether a class with no explicit inheritance should extend Object or your custom class. If it chose the latter for every class with no explicit inheritance, it would introduce compilation errors in most cases or, if you're particularly unlucky, surprising behavior that only manifests at runtime. If it chose the former and you'd have to explicitly opt-in your classes for this, what's the point?

(The same, of course, would happen if you wanted to implicitly implement an interface: All classes that don't really implement that interface would break and cause compilation errors. Or, if you're unlucky, the interface would match unrelated methods in a class that happen to have a matching signature and cause strange behavior that you'd find out about by testing.)

like image 106
Theodoros Chatzigiannakis Avatar answered Dec 04 '22 13:12

Theodoros Chatzigiannakis


This is supported at a very low level within the runtime, a value of a value type can be embedded in an object that's stored on the garbage collected heap. Thus turning a value type in a reference type and creating the illusion that every value type inherits from ValueType and Object. Which are reference types.

The mechanism is calling boxing in .NET, the value type value literally gets "boxed" into an object. And there's an unboxing conversion to go back from the object with the boxed value to a value of a value type. The C# compiler will emit these conversions automatically based on your source code. There are dedicated opcodes for this is IL, the Intermediate Language that the C# compiler emits from your source code. Respectively the Opcodes.Box and Opcodes.Unbox instructions. Opcodes.Constrained is an instruction that can optimize the conversion. The jitter knows how to implement them and generates very efficient inline machine code to make these conversions.

Boxing is a highly specific to System.Object being a base class in the type hierarchy and the plumbing that supports it is highly specific to value type values. It is not an extensible mechanism, you cannot add your own IL instructions nor extend the jitter nor give the C# language new syntax. If you need your types to have a common base interface or class then you have to declare them that way in your code. The dynamic keyword may be attractive to you, it isn't clear from the question.

like image 20
Hans Passant Avatar answered Dec 04 '22 12:12

Hans Passant