Спецификация параметров типа С#

Некоторые специальные типы CLI из библиотеки mscorlib (ArgIterator, TypedReference и RuntimeArgumentHandle) не могут использоваться в качестве параметров типового типа для создания общих типов/методов:

void Foo<T>() { }
void Bar() { Foo<ArgIterator>(); }

предоставляет ошибку компилятора:

error CS0306: The type 'System.ArgIterator' may not be used as a type argument

Но это не документировано вообще в спецификации С#.

Являются ли эти типы частью спецификации CLI или эти типы, предоставляемые реализацией CLR, и описанное выше поведение не должно быть документировано в спецификации С#?

Ответ 1

Во-первых, Джон снова прав - эти ребята - очень специальные типы, значения которых не конвертируются в объект и поэтому не могут использоваться как аргументы типа. Все аргументы типа должны быть типами, значения которых конвертируются в объект.

Чтобы ответить на вопрос о документации:

Ни одна из специальных функций для обработки вариационных методов не документирована. Они не являются частью языка С# - соответствующая реализация языка не требуется, чтобы иметь возможность взаимодействовать с языками, поддерживающими вариационные методы. Эти функции также не задокументированы в MSDN как часть документации компилятора. Это не "официально поддерживаемые" функции.

Это печально, но есть только такой бюджет, и я думаю, что большинство людей согласятся с тем, что нам лучше писать функции и исправлять ошибки, чем тратить деньги на документирование функций, которые буквально 99,99% наших пользователей никогда не будут, когда-либо использовались, даже если они были поддержаны, а это не так.

Если вы хотите сделать interop в С# с помощью вариативных методов, вы сами по себе. Удачи!

Ответ 2

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

Я не могу найти, где это задокументировано (он документирован для указателей в 4.4.1), но Эрик Липперт упомянул об этом в комментарии на днях.

Это просто вопрос интереса, или вы пытаетесь на самом деле что-то делать с помощью такого рода вещей?

Ответ 3

Все три примера, которые вы предоставили, это структуры, а не классы, поэтому я подозреваю, что ключ к этой проблеме. Пример, представленный в документации по сообщению компилятору, также указывает, что если вы используете указатель на тип в родовом выражении, он потерпит неудачу.

Ответ 4

Раздел 8.2.4 Спецификация CLI вызывает типы значений, которые могут содержать указатели в типах стека оценки типа "по-видимому" и говорят что они не могут быть в коробке. Он явно вызывает System.RuntimeArgumentHandle и System.TypedReference в качестве примеров таких типов, но не содержит исчерпывающего списка. В разделе 9.4 далее указывается, что типы ссылок, похожие на типы, а System.Void не могут использоваться для создания типичных типов или методов.

Ответ 5

Как комментарий, здесь еще немного удовольствия, когда вы пытаетесь скомпилировать код с этим типом, который не конвертируется в объект. Все методы здесь появляются в виде предложений Visual Studio при вводе . (точка).

  ArgIterator.ReferenceEquals(new object(), new object());  // OK; static method inherited from System.Object

  var strange = default(ArgIterator);
  strange.End();          // OK; non-virtual method defined in the struct
  strange.GetHashCode();  // OK; method overridden in the struct
  strange.ToString();     // compile-time error; method overriden in System.ValueType, inherited but not overridden in the struct
  strange.GetType();      // compile-time error; non-virtual method inherited from System.Object