Как получается, что структура, содержащая ValueTuple, может удовлетворять неуправляемым ограничениям, а сама ValueTuple - нет? - PullRequest
0 голосов
/ 01 января 2019

Рассмотрим следующие типы:

  • (int, int) → управляемый.
  • struct MyStruct { public (int,int) Value; } → неуправляемый!

Проблема: Неуниверсальная структура MyStruct, имеющая управляемого члена (int,int), была оценена как управляемый тип.

Ожидаемое поведение: Структура, которая содержит управляемого члена, должнасчитается управляемым, точно так же, как struct MyStruct { int? Value; } считается управляемым.

Кажется, что оба типа ведут себя против документации [1] и [2] .

Пример 1 - неуправляемое ограничение

class Program
{
    static void DoSomething<T>() where T : unmanaged { }
    struct MyStruct {  public (int, int) Value; }
    static void Main(string[] args)
    {
        DoSomething<MyStruct>();    // → OK
        DoSomething<(int, int)>();  // → Shows compile-time error
    }
}

Ошибка CS8377 Тип '(int, int)' должен быть ненулевым типом значения, наряду ссо всеми полями на любом уровне вложенности, чтобы использовать его в качестве параметра 'T' в универсальном типе или методе 'Program.DoSomething ()'

Пример 2 - указатель или sizeof

При использовании приведенной выше структуры поведение указателей одинаковое для указателей или оператора sizeof:

unsafe 
{
    (int, int)* p1;  // → Compile-time error, 
    MyStruct* p2;    // → Compiles
}

Ошибка CS0208 Невозможно получить адрес, получить размерили объявить указатель на управляемый тип ('(int, int)')

Вопрос

  1. Как работает структурасодержащий ValueTuple считается unmanaged и может удовлетворять ограничению unmanaged, в то время как ValueTuple считается управляемым?

  2. Как структура, имеющая ValueTupple<T1, T2>, и структура, содержащаяNullable<T> трактуются по-разному?


Примечание 1: ИМО проблема отличается от Предложение: Unmanaged сконструированные типы (адресованные DavidG в комментариях), поскольку MyStruct не является универсальным, с другой стороны, в то время как int? и (int,int) оба управляются, но struct MyStruct { int? Value; } и struct MyStruct { (int, int) Value; } оцениваются по-разному.

1 Ответ

0 голосов
/ 03 января 2019

Спасибо за сообщение.Это просто ошибка в компиляторе.Кортеж при использовании в качестве поля должен регистрироваться как универсальный тип и, следовательно, недопустим в unmanaged type.Похоже, вместо этого он оценивается как тюльпан и пропускает эту проверку.

Хорошей новостью является то, что в C # 8.0 это ограничение будет снято.Тип (int, int) является действительным unmanaged type.

...