为什么这个程序会编译?
class Program
{
static void Main(string[] args)
{
throw null;
}
}
从 C#语言规范的8.9.5开始,
带有表达式的
throw
语句会抛出通过计算表达式而产生的值。表达式必须表示类类型System.Exception
的值,类型派生自System.Exception
的类型或具有System.Exception
(或其子类)的类型参数类型的有效值基类。如果对表达式的评估产生null
,则会抛出System.NullReferenceException
。
显然,null
评估为null
,所以最后一句是这种行为的来源,但它是如何实现的?尝试抛出不是从System.Exception
派生的其他值会导致编译器错误error CS0155: The type caught or thrown must be derived from System.Exception
。
proposed duplicate的最佳答案始于(强调我的):
因为语言规范需要
System.Exception
类型的表达式(因此,null
在该上下文中是有效的)...
表达式null is System.Exception
的计算结果为false,并产生编译器警告warning CS0184: The given expression is never of the provided ('Exception') type
,所以我很自然地认为null
在System.Exception
的{{1}}无效的断言是必需的。