У каждого класса есть список определений для:
Constructors
Destructors
Fields
Methods
Properties
Indexers
Delegates
Events
Nested Classes
Объект является универсальным типом, потому что каждый класс наследуется от него, но не наоборот.Эти определения не одинаковы для каждого класса, поэтому ваш компилятор может решить, какие типы вы можете назначить / привести друг к другу.
Затем вы делаете: string x = (object)null;
Компилятору все равноэто значение, которое вы пытаетесь присвоить своему x в первую очередь, но оно проверяет определения типов строки и просто не позволяет вам стрелять в собственную ногу и генерирует ошибку, потому что это несоответствие типов.