Сценарий очень редок, но довольно прост: вы определяете общий класс, а затем создаете вложенный класс, который наследуется от внешнего класса и определяет ассоциативное поле (типа self) внутри вложенного. Фрагмент кода проще, чем описание:
class Outer<T>
{
class Inner : Outer<Inner>
{
Inner field;
}
}
после декомпиляции IL, код С# выглядит так:
internal class Outer<T>
{
private class Inner : Outer<Outer<T>.Inner>
{
private Outer<Outer<T>.Inner>.Inner field;
}
}
Это кажется достаточно справедливым, но когда вы меняете объявление типа поля, все становится сложнее. Поэтому, когда я изменяю объявление поля на
Inner.Inner field;
После декомпиляции это поле будет выглядеть так:
private Outer<Outer<Outer<T>.Inner>.Inner>.Inner field;
Я понимаю, что классная "натура" и наследование не совсем ладят друг с другом, но почему мы наблюдаем такое поведение? Является ли объявление типа Inner.Inner
измененным типом вообще? Существуют ли в этом контексте типы Inner.Inner
и Inner
?
Когда все становится очень сложно
Вы можете увидеть декомпилированный исходный код для класса ниже. Он действительно огромный и имеет общую длину 12159 символов.
class X<A, B, C>
{
class Y : X<Y, Y, Y>
{
Y.Y.Y.Y.Y.Y y;
}
}
Наконец, этот класс:
class X<A, B, C, D, E>
{
class Y : X<Y, Y, Y, Y, Y>
{
Y.Y.Y.Y.Y.Y.Y.Y.Y y;
}
}
приводит к сборке 27.9 MB (29,302,272 bytes)
и Total build time: 00:43.619
Используемые инструменты
Компиляция выполняется под компиляторами С# 5 и С# 4. Декомпиляция выполняется dotPeek. Конфигурации сборки: Release
и Debug