Путаница с ограничениями Nullable <T> - PullRequest
10 голосов
/ 08 апреля 2010

Приветствую всех. Прошу прощения, если об этом уже спрашивали (искали напрасно) или оно действительно очень простое, но я просто не могу его получить. Определение MSDN типа Nullable гласит, что оно определено следующим образом:

[SerializableAttribute]
public struct Nullable<T>
where T : struct, new()

Таким образом, вопрос довольно прост: как возможно это определение? Или это просто опечатка? Каждый тип значения уже имеет конструктор по умолчанию. Действительно, когда я пытаюсь скомпилировать что-то подобное, компилятор разумно говорит, что нельзя применять оба ограничения одновременно, потому что второе неявно включено в первое.

Заранее спасибо.

Ответы [ 3 ]

12 голосов
/ 08 апреля 2010

Я думаю, что это просто ошибка в документации.Если вы посмотрите на тип Nullable<T> в Reflector или используете команду «Перейти к определению» в VS, он показывает только ограничение struct.


EDIT

Я снова подумал об этом и провел небольшой тест:

var attributes = typeof(Nullable<>).GetGenericArguments()[0].GenericParameterAttributes;
Console.WriteLine(attributes);

Этот код выдает следующий вывод:

NotNullableValueTypeConstraint, DefaultConstructorConstraint

Таким образом, согласно рефлексии, T в Nullable<T> имеет ограничение new() ... Это означает, что, несмотря на то, что оно недопустимо в C #, оно должно быть действительным дляCLR.

Таким образом, документация является правильной и неправильной: это правда, что T в Nullable<T> имеет ограничение "конструктор по умолчанию", но объявление C #, которое оно показывает, является неправильным ...

Это на самом деле не очень удивительно, поскольку документация генерируется из метаданных сборки (и, конечно, комментариев XML).В генераторе документации должна быть ошибка ...

5 голосов
/ 08 апреля 2010

C # требует, чтобы типы значений имели открытые конструкторы по умолчанию, а CLR - нет.

Если вы определили тип в языке, который поддерживает определение структуры этого типа (я полагаю, C ++ / CLI позволяет это), возникнет двусмысленность относительно того, когда он вызывается.

3 голосов
/ 08 апреля 2010

Если вы посмотрите на разборку IL, вы увидите, что она имеет ограничение конструктора:

.class public sequential ansi serializable sealed beforefieldinit Nullable<valuetype (System.ValueType) .ctor T>

Если документация генерируется непосредственно из метаданных сборки, может, в этом причина?

...