Home » c# » What does Eric Lippert mean by “you need to know what the base class is to determine what the base class is”?

What does Eric Lippert mean by “you need to know what the base class is to determine what the base class is”?

Posted by: admin February 22, 2018 Leave a comment

Questions:

I just read this interesting article by Eric Lippert, Top 10 Worst C# Features. Near the end he states:

The rules for resolving names after the aforementioned colon are not
well founded; you can end up in situations where you need to know what
the base class is in order to determine what the base class is.

By colon he is referring to the inheritance operator (e.g. Dog : Animal).

What situation is Eric referring to? Can anyone provide a code sample?

Answers:

This can happen in convoluted scenarios with generics, inheritance, and nested classes:

class Base<T> {
    public class Inner {}
}

class Derived : Base<Derived.Inner2> {
    public class Inner2 : Inner {}
}

Result

  • To determine Derived‘s base class, we need to bind Derived.Inner2.
  • To bind Derived.Inner2, we need to resolve the Inner symbol.
  • The Inner symbol is inherited from its containing scope’s base class, so we need to determine Derived‘s base class again.
Questions:
Answers:

SLaks gives a good answer; see my comments for some additional notes.

As I said in the comments I am looking for my old notes on this subject and if I find them, I’ll write a blog. Here’s a fun additional example. This program is legal. Are the meanings of N in the class declaration and the field declaration the same or different? If they are the same, what is a fully-qualified type expression for them? If they are different, why does the specification require that they be different?

public class N {}
public class B<T> 
{
    public class N {}
}

public class D : B<N> // base class
{
  N n;  // field
}

This illustrates the fundamental problem: name lookup requires that the base class is known, but the base class is looked up by name.

Now think about how interfaces work in the mix. Suppose class D also implements an interface IN, similarly nested in B and available globally. Does the interface lookup resolve to the base class or the global namespace? These are the sorts of questions that you have to resolve when you’re writing a compiler.