Интересно о C#: все типы наследуются от object
Этим постом стартую серию постов на тему "Интересно о C#", где буду рассматривать интересные фичи о языке C# и .NET в целом.
Итак, мы знаем, что все типы в C# являются наследниками от object (даже простые типы - int, double, bool и т.д по той причине, что они, по сути, являются алиасами для Int32, Double, Boolean соответственно). Итак, все численные типы (включая перечисления, структуры и nullable типы), классы, массивы и делегаты наследуются от object. Заблуждение заключается в том, что не все типы унаследованы от object. Давайте рассмотрим подробнее.
Интерфейсы, не будучи классами, не наследуются от object. В то же время они являются конвертируемыми в object, потому что в рантайме все экземпляры должны иметь конкретный тип. Таким образом, интерфейсы наследуются от других интерфейсов, в то же время когда тип object не является интерфейсом.
Также типы параметров типов (type parameter type) также не наследуются от object. Можно создать переменную, у которой тип - тип параметра типа (извините за тавтологию). Так как generic типы и методы используются только в рантайме, когда им передаются уже конкретные типы, они также являются конвертируемыми в object. именно поэтому нельзя создать конструкцию типа IEnumerable
Поэтому правильный вариант фразы звучит как "любой не ссылочный тип в C# является конвертируемым в object".