Это вызвано дизайнерским решением Windows, принятым много лет назад. Нижние 64 килобайта адресного пространства зарезервированы. О доступе к любому адресу в этом диапазоне сообщается с исключением нулевой ссылки вместо основного нарушения доступа. Это был мудрый выбор, нулевой указатель может производить чтение или запись по адресам, которые на самом деле не равны нулю. Например, читая поле объекта класса C ++, оно имеет смещение от начала объекта. Если указатель объекта равен нулю, код будет бомбить чтение по адресу, который больше 0.
C # не имеет такой же проблемы, язык гарантирует, что нулевая ссылка будет перехвачена, прежде чем вы сможете вызвать метод экземпляра класса. Однако это зависит от языка, это не функция CLR. Вы можете написать управляемый код в C ++ / CLI и генерировать ненулевые разыменования нулевого указателя. Вызов метода для объекта nullptr работает. Этот метод весело выполнится. И вызвать другие методы экземпляра. Пока он не попытается получить доступ к переменной экземпляра или вызвать виртуальный метод, который требует разыменования this , kaboom затем.
Гарантия C # очень хорошая, она значительно упрощает диагностику проблем с нулевыми ссылками, поскольку они генерируются на месте вызова и не бомбят где-то внутри вложенного метода. И это существенно безопаснее: переменная экземпляра может не вызывать исключение для очень больших объектов, когда ее смещение превышает 64 КБ. Довольно сложно сделать это в управляемом коде, в отличие от C ++. Но не приходит бесплатно, объяснено в этом сообщении в блоге .