typeof дает исключение «Ожидаемый тип» для неструктурированного вложенного универсального типа - PullRequest
6 голосов
/ 04 ноября 2011

Обычно получить неструктурированный универсальный тип довольно просто, используя typeof :

Type genericType = typeof( Func<> );

Я ожидал бы, что следующее также будет работать, но оно выдает ошибку компилятора Type expected.

Type genericNestedType = typeof( Func<Func<>> );

Относительно легко обойти это, используя вместо этого Func<Func<object>>. Однако, когда вы «потребляете» тип, вы должны помнить, что вызываете GetGenericTypeDefinition().

Сценарий, в котором вы хотели бы «заполнить» все неназначенные параметры универсального типа, был бы невозможен. Опять же, было бы относительно легко создать фиктивный тип вместо того, чтобы указывать эти параметры. (например, Func<Func<ToReplace, object, int>>)

Есть ли какая-либо причина, по которой typeof не работает на вложенных универсальных неструктурированных типах?

Ответы [ 2 ]

6 голосов
/ 04 ноября 2011

Я не верю, что это ошибка компилятора - раздел 7.6.11 спецификации C # 4 (оператор typeof), похоже, не дает какого-либо синтаксиса, который бы приводил его к допустимости; Func<Func<>> не является ни действительной типом конструкции, ни допустимым несвязанным именем типа конструкции.

Что касается почему это так, хотя: я предполагаю, что это очень редко необходимо (я никогда даже не думал использовать его раньше, и не слышал, чтобы кто-то его запрашивал) и поэтому считается, что дополнительная сложность в проектировании языка, реализации компилятора и тестировании перевешивает выгоду. Это часто имеет место с вопросами «почему у C # нет функции X», поскольку Эрик Липперт любит указывать:)

Я был приятно удивлен, увидев, что можно сделать во время выполнения:

Type unbound = typeof(Func<>);
Type partiallyBound = unbound.MakeGenericType(new[] { unbound });
Console.WriteLine(partiallyBound);        

Я наполовину ожидал, что он будет недействительным в системе типов .NET, хотя, я полагаю, это могло вызвать другие проблемы.

0 голосов
/ 04 ноября 2011

Основная причина Я подозреваю, просто в том, что typeof( Func<Func<>> ) не будет очень полезным .Это не полностью сконструированный тип, поэтому вы не можете использовать для чего-либо - и это также не определение общего типа, поэтому вы не можете вызвать MakeGenericType(...), чтобы добавить T к внешнему типу - это внутренний тип, который нуждается в T, поэтому вам нужно сделать что-то вроде:

var closedType = type.GetGenericTypeDefinition().MakeGenericType(
    type.GetGenericTypeArguments().MakeGenericType(finalT)
);

Так просто ... нет реальногоиспользовать в typeof(Func<Func<>>) - проще начинать с нуля.

...