This is one of the few areas where I think C# went backwards from C++.
In C++, you could write
void foo(Bar& bar) { /*...*/ }
to quite clearly indicate to both the compiler and other humans that foo took an actual instance of Bar. Yes, it is possible--with effort--to pass foo a null reference but that's not really legal C++.
Your only "solution" (of sorts) in C# is to make your classes structs instead, as value types in .NET can't be null (in your example, b can't ever be null because it is a System.Int32). The call to bar() will not compile:
class A { } struct B { } static void foo(A a) { } static void bar(B b) { } static void Main(string[] args) { foo(null); bar(null); }
It certainly seems like it would have been nice for C# to have made it (much) more difficult to have null references; F#, for example, has no nullable types.
For some interesting commentary related to this matter, read Null References: The Billion Dollar Mistake (and the comments).
Edit: A February 2013 footnote from Eric Lippert says "... it just so happened that when C# was first implemented it had always-nullable reference types, ... it seems plausible that Nullable<T> could have been implemented to work on any type, and reference types would then be non-nullable by default. We could have a type system where Nullable<string> was the only legal way to represent "a string that can be null". ... "