.NET: Почему у вложенного класса генерики объявляются во внешнем классе? - PullRequest
0 голосов
/ 22 февраля 2019

Поскольку Type.FullName немного уродлив, мне нужно сделать свой красивый конструктор имен.Но когда я использовал Type.GetGenericArguments(), я столкнулся с одной проблемой.

Универсальный T внешнего класса C1 всегда распространяется на вложенные классы C2 и C3.

class C1<T> {
    public class C2<T1, T2> {
    }
    public class C3 {
    }
}

typeof( C1<> ).ToString(); // C1`1[T]
typeof( C1<>.C2<,> ).ToString(); // C1`1+C2`2[T,T1,T2]
typeof( C1<>.C3 ).ToString(); // C1`1+C3[T]

Два вопроса:

  • Как определить, пришел ли универсальный тип из внешнего класса или нет?
  • В чем причина такого поведения?

1 Ответ

0 голосов
/ 03 марта 2019

Параметры типа не «наследуются» вложенными классами в CIL.Там ваш класс выглядит следующим образом:

.class private auto ansi beforefieldinit C1`1<T> extends [mscorlib]System.Object
{
    .class nested public auto ansi beforefieldinit C2`2<T, T1, T2> extends [mscorlib]System.Object
    {
    }

    .class nested public auto ansi beforefieldinit C3<T> extends [mscorlib]System.Object
    {
    }
}

Поскольку определение вложенного типа на самом деле не зависит от родительского типа, внешние обобщенные аргументы не должны быть ему доступны, и поэтому было решено, что онидолжен повторяться явно, как это делает C #, но есть поддержка языков, которые работают по-другому (где C1<>.C3 может быть конкретным типом).

Тогда возникает вопрос о получении выражения типа C #из. NET типа.Вам может повезти с CodeDOM или просто предположить, что если общие параметры вложенного типа имеют то же имя, что и параметры родительского типа, вы можете опустить их при создании строки.

Итак, повторюсь, универсальные параметры не могут быть получены из внешнего класса в .NET, это просто поведение C #.Если вы предполагаете, что класс был создан в C #, вы можете просто удалить параметры, основываясь на их именах.

...