Ответ 1
Это вариация головоломки, которую я опубликовал в своем блоге много лет назад:
http://blogs.msdn.com/b/ericlippert/archive/2007/07/27/an-inheritance-puzzle-part-one.aspx
и Сайрус опубликовали в своем блоге до этого:
http://blogs.msdn.com/b/cyrusn/archive/2005/08/01/446431.aspx
См. обсуждение там для деталей.
Вкратце: что означает B
в class C : B
? Проверьте контейнер, class B
. Он содержит любой тип, называемый B
? Нет. Затем проверьте базовый класс контейнера. Базовый класс контейнера A<int>
. Он содержит что-либо называемое B
? Да. Таким образом, это означает class C : A<int>.B
.
Теперь мы говорим, что c
есть A<string>.B.C
. Мы называем метод A<string>.B.C.c()
Что такое T
на всем протяжении A<string>
? Очевидно, string
. Поэтому c.c()
печатает string
для T
.
Теперь мы называем A<string>.B.C.b()
, но такого метода в A<string>.B.C
нет. Где он получает этот метод? Из его базового класса. Что это за базовый класс? A<int>.B
. Поэтому мы называем A<int>.B.b()
. Что такое T
на протяжении всего A<int>
? Очевидно, int
.
Теперь мы переходим к A<string>.B.D.d()
. Базовый класс не имеет значения. T
string
на протяжении A<string>
.
И наконец A<string>.B.D.b()
. На A<string>.B.D
такого метода нет, поэтому он должен получить его из своего базового типа. T
string
на протяжении A<string>
, поэтому базовый тип A<string>.B
. Поэтому это вызывает A<string>.B.b()
.
Если это не имеет смысла для вас, заклинайте все. Пусть подстановка String для T:
class A_string
{
public class B : A_int
{
public void b()
{
Console.WriteLine(typeof(string).ToString());
}
public class C : A_int.B // Note!
{
public void c()
{
Console.WriteLine(typeof(string).ToString());
}
}
public class D : A_string.B
{
public void d()
{
Console.WriteLine(typeof(string).ToString());
}
}
}
}
ОК, это один из типов. Теперь сделаем то же самое для int:
class A_int
{
public class B : A_int
{
public void b()
{
Console.WriteLine(typeof(int).ToString());
}
public class C : A_int.B // Note!
{
public void c()
{
Console.WriteLine(typeof(int).ToString());
}
}
public class D : A_int.B
{
public void d()
{
Console.WriteLine(typeof(int).ToString());
}
}
}
}
Теперь, учитывая эти типы, должно быть ясно, какие A_string.B.C.c()
, A_string.B.C.b()
и т.д. все распечатываются.