Это одна из немногих областей, где я думаю, что C # отошел от C ++.
В C ++ вы могли бы написать
void foo(Bar& bar) { /*...*/ }
, чтобы довольно четко указать и компилятору, и другим людям, что foo
взял фактический экземпляр Bar
. Да, возможно - с усилием - передать foo
нулевую ссылку, но это не совсем допустимо в C ++.
Ваше единственное «решение» (своего рода) в C # - вместо этого сделать ваши class
es struct
s, поскольку типы значений в .NET не могут быть null
(в вашем примере, b не может быть null
, потому что это System.Int32
). Вызов bar()
не скомпилируется:
class A { }
struct B { }
static void foo(A a) { }
static void bar(B b) { }
static void Main(string[] args)
{
foo(null);
bar(null);
}
Очевидно, что для C # было бы неплохо сделать (намного) более трудным иметь ссылки null
; Например, в F # нет обнуляемых типов.
Для некоторых интересных комментариев, связанных с этим вопросом, прочитайте Нулевые ссылки: Ошибка в миллиарде долларов (и комментарии).
Редактировать: Сноска за февраль 2013 года от Эрик Липперт говорит: "... так сложилось, что когда C # был впервые реализован, у него всегда были обнуляемые ссылочные типы, ... кажется правдоподобным, что Nullable<T>
мог бы быть реализован для работы с любым типом, и тогда ссылочные типы были бы не обнуляемыми по умолчанию. У нас могла бы быть система типов, где Nullable<string>
был единственным допустимым способом представления "строки, которая может быть null
". ..."