tags:

views:

292

answers:

3

Question is simple and asked in the title.

C# 4.0 Specification says: (§4.2.2)

The object class type is the ultimate base class of all other types. Every type in C# directly or indirectly derives from the object class type.

Eric Lippert says: ( http://blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx)

Interface types, not being classes, are not derived from object.

Reality says:

Type t = typeof(ICloneable).BaseType;
Console.WriteLine(t == null);

True

So is spec wrong or what? Whom to believe?

+3  A: 

Believe Eric Lippert - very much involved with the spec and the C# implementation - the defacto source, if you will. Specs are subject to being incorrect, not giving good enough explanations, or being out-of-date.

Eric - not so :-)

Update: turns out people don't like my light-hearted reference to the person arguably most knowledgable on the subject.

Serious answer: Eric explains where interfaces sit with regards to inheriting from Object quite clearly in his post - however this doesn't mention any changes / updates to subsequent versions of the .NET Framework, so alas, he could be out-of-date...

Adam
lol, I'd love to know who downvoted, Eric is very often the person who answers these questions - and he went to great lengths in that post to explain the situation.
Adam
+11  A: 

It's not quite as simple a question as you might think :)

Interfaces don't derive from object but you can call the members of object on them. So you can call ToString() on an expression which has a compile-time type of IDisposable, for example.

Ironically, I overhead a conversation between Neal Gafter and Eric at NDC discussing exactly this point...

I believe section 4.2.2 of the spec is over simplified, unfortunately. Hopefully Mads and Eric will fix it up for a future release - I'll mail them to make sure they see this question.

I'm also struggling to find anything in the spec to back up the rest of this answer. Section 3.4.5 of the C# 4 spec comes as close as I can find:

The members of an interface are the members declared in the interface and in all base interfaces of the interface. The members in class object are not, strictly speaking, members of any interface (13.2). However, the members in class object are available via member lookup in any interface type (7.4).

The conversion from an interface type to object is covered by section 6.1.6:

The implicit reference conversions are:

  • From any reference-type to object and dynamic.
Jon Skeet
Anything that implements an interface (classes or structs) is going to derive from `object`. I'm not aware of the other non-object types (e.g. pointers) being able to implement interfaces.
Tim Robinson
Would you say the spec is correct in that an interface *indirectly* inherits? Well, it doesn't inherit in the technical sense, but the end result appears to behave as such.
Adam
I can't catch difference between *derive* and *have an effective base type*. Even if declaration of class and interface looks very similar they are essentially different, interface is just a contract. So since in .net no class can derive from something different than Object every interface reference can be cast to object. but this doesn't mean for me that they actually derive from object.
Andrey
@Andrey: Effective base classes come into play in type inference and various things. However, I'm not sure that I was right about that section. Editing...
Jon Skeet
But this: "However, the members in class object are available via member lookup in any interface type (7.4)." is conclusion from fact that there is single root in hierarchy in .net. If we had "System.Object" and "System.AnotherObject" which was not descendant of Object this will not work.
Andrey
@Andrey: Yes, C# assumes a single root object type.
Jon Skeet
+6  A: 

Jon is (as usual) spot on. It is not as easy as you think!

The spec is vague and slightly contradictory. In this particular case it is probably best to squint a little bit and get the gist of what the spec means to convey rather than narrowly parsing it for precise definitions.

The simple fact of the matter is that "inheritance" is a very overused term in object-oriented programming. (I seem to recall that C++ has six different kinds of inheritance, though I'd be hard pressed to name them all on short notice.)

If I had my druthers then the C# specification would clearly call out a difference between inheritance, which is a code-sharing technique for class (and delegate) and struct (and enum) types, and interface implementation which is a requirement that an implementing type have a certain set of public members. Those two things seem conceptually very different to me; one is about sharing implementation details and the other is about requiring public members.

However, the spec does not do so; it conflates the two under the rubric of inheritance. Given that these two somewhat different things have the same name in the spec, it is hard to reason clearly and precisely about the differences between them.

I personally prefer to think that object is not the "base type" of any interface, and that the members of object are not inherited by the interface. That you can call them on an instance of an interface is more like a courtesy extended to you by the compiler so that you do not have to insert a cast to object in there.

Eric Lippert