Рассмотрим следующие типы:
(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)')
Вопрос
Как работает структурасодержащий ValueTuple
считается unmanaged
и может удовлетворять ограничению unmanaged
, в то время как ValueTuple
считается управляемым?
Как структура, имеющая ValueTupple<T1, T2>
, и структура, содержащаяNullable<T>
трактуются по-разному?
Примечание 1: ИМО проблема отличается от Предложение: Unmanaged сконструированные типы (адресованные DavidG в комментариях), поскольку MyStruct
не является универсальным, с другой стороны, в то время как int?
и (int,int)
оба управляются, но struct MyStruct { int? Value; }
и struct MyStruct { (int, int) Value; }
оцениваются по-разному.