Um... Because it's null.
In C#, a reference type is a pointer to something. A null pointer isn't pointing to anything. You are asking, "What type of thing would this point to if it was pointing to something". That's sort of like getting a blank sheet of paper, and asking, "What would this say if it had something written on it?"
UPDATE: If the framework can't know the type of a null pointer, can't it know what type it's supposed to be? Well, it might. Then again, it might not. Consider:
MyClass myobj = null;
int hash = myobj.GetHashCode();
Unless you overrode it in MyClass, GetHashCode is defined in System.Object. Should you get a complaint that myobj needs to be a System.Object? Now, when we check ourselves, we're completely free to specify the required type.
SomeFunc(MyClass myparam)
{
if (myparam == null)
throw new ArgumentNullException("myparam must be a MyClass object");
}
But now we are talking about application code, not CLR code. Which makes you "real" question "Why don't people write more informative exception messages?", which is, as we say here at SO "subjective and argumentative"
So, you basically want the system level exception to know the type information which is only known at the applications level, which we'd need so way to communicate. Something like:
SomeFunc(MyClass myparam)
{
if (myparam == null)
throw new ArgumentNullException("myparam", typeof(MyClass));
}
But that's not really buying us much, and if you really want it, you could write it yourself:
public class MyArgumentNullException : ArgumentNullException
{
public MyArgumentNullException(string name, Type type)
:base(name + "must be a " + type.Name + " object");
}