Почему именно эти "специальные классы"?

После прочтения этого вопроса, спрашивая, что такое "Специальный класс", я оставляю вопрос, почему шесть классов System.Object, System.Array, System.Delegate, System.Enum и System.ValueType были выбраны и жестко закодированы в качестве специальных классов, не позволяя им использоваться в качестве ограничений для общих классов или методов.

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

PS: специальные классы поднимают ошибку компиляции CS0702, когда делается попытка использовать их в качестве ограничений.

Ответы

Ответ 1

Эти классы были уже разными до того, как общие ограничения или даже дженерики были добавлены в платформу .NET и поддержка для них добавлена ​​на язык С#.

Что у каждого из них есть общее, заключается в том, что наследование от них отличается от других типов:

System.Object: На С# нельзя наследовать не.

System.Array: Вы наследуете это путем создания массива существующего типа (Array x = new int[2]; и т.д.)

System.Delegate: Вы наследуете это, создавая delegate (который затем выводится из MulticastDelegate, а также "особый тип", который происходит от delegate).

System.Enum: Наследуем это, создавая enum.

System.ValueType: Вы наследуете это, создавая struct.

Теперь обратите внимание, что помимо new() общие ограничения связаны с наследованием или реализацией интерфейсов (что во многом похоже на наследование). Действительно, другие ограничения заключаются в том, что вы не можете использовать тип указателя, и вы не можете использовать закрытый тип; два случая, когда вы не можете иметь производный тип в любом случае (хотя запрет на запечатанные типы в первую очередь связан с тем, что вы, вероятно, создаете общий тип или метод, когда вам тоже этого не нужно, и пытаетесь защитить вас от вас самих).

И поскольку такой код, основанный на свойствах наследования (в качестве ограничений), когда сталкиваются с особыми случаями о наследовании, вероятно, сам по себе будет связан с особыми случаями. Эти особые случаи были рассмотрены простейшим способом: запретив их.

Во многих из этих случаев значение также меньше:

System.Object: Так как единственные типы, которые не могут быть преобразованы в System.Object, являются типами указателей, и в любом случае они не могут использоваться как общие параметры, любое такое ограничение является избыточным.

System.Array:. Вы можете определить в терминах типов элементов: void DoSomethingWithArray<T>(T[] array) и т.д.

System.Delegate: Это было бы полезно, хотя во многих случаях мы можем определять в терминах параметров и/или возвращаемых типов, но есть случаи, когда это не улавливается.

System.Enum: Было бы полезно.

System.ValueType: Уже рассмотрено; сдерживать как struct. И наоборот, мы можем также ограничить как class, чтобы исключить этот случай, поэтому у нас есть опция "не унаследована от...", которой мы не располагаем.

Нельзя отрицать, что возможность сдерживания в терминах delegate, MulticastDelegate или enum не была бы полезна (возможно, наиболее того, мы enum), но с точки зрения оправдания дополнительной работы для охватывают эти типы, другие будут давать небольшую выгоду или не приносят никакой пользы, поэтому преимущество меньших ограничений уменьшается.