1

在Delphi中,如果在对象的构造过程中出现异常:任何分配的内存都会被释放并抛出异常。例如,保证以下内容要么返回有效Camera对象,要么抛出异常:

Camera c = new Camera();

永远不必检查结果变量是否为空:

Camera c = new Camera();
if (c == null)
   throw new Exception("Error constructing Camera") //waste of time

在 CLR 中也是如此吗?

是否还有其他语法结构可以保证返回值有效或抛出异常?

  • 创建结构(例如矩形)?
  • 获取枚举成员?
  • Object.ToString() 的结果?
  • 数学运算?

在执行数学的情况下:

Int32 aspect = 1650.0 / 1080.0;
if (aspect == null) 
   throw new Exception("Division of two numbers returned null")
4

2 回答 2

3

.Net 中的构造函数保证返回对象类型的非空实例。实例是否有效取决于类型的各个语义。

构造函数中抛出的异常不会被 CLR 任意吞下(尽管用户代码可以吞下它们)。CLR 将像在任何其他方法中抛出的异常一样传播异常,并且最终将正确地对对象进行垃圾收集。

至于你提到的其他情况

  • 创建结构:根据定义,结构不能为空。构造函数中抛出的异常会正常传播
  • 获取枚举成员:枚举是底层的结构/值类型,也永远不会为空
  • Object.ToString() 的结果:这可以(很遗憾地)为空。String 是一种引用类型,从 ToString 覆盖返回 null 是完全合法的(请不要)。
  • 数学运算:这在很大程度上取决于项目的溢出设置和所使用的特定类型(整数与浮点)。

这个数学问题几乎值得自己回答。一方面,对原始类型进行数学运算的结果永远不会为空。但它仍然可能无效。例如,以下代码不会抛出,但结果是否有效在很大程度上取决于您的具体情况

float f1 = 1.0;
float f2 = f1 / 0;

此时 f2 是一个非常具体的浮点值,不代表实数。它有效吗?取决于您的用例。

于 2009-06-28T04:26:16.843 回答
1

是的。我想这样说(因为失败也可能意味着逻辑失败):如果构造函数没有抛出异常,则返回值保证为非 -null所以你永远不必执行这样的检查。

创建结构(例如矩形):Astruct根本不可能nullNullable类型被认为是完全不同的类型,即typeof(int?) != typeof(int))。调用结构的构造函数要么会因抛出异常而失败,要么会返回一个实例。

获取枚举成员:Anenum只是一组常量。没有什么能比得上“在运行时获取成员”。它在编译时被替换。

的结果Object.ToString():与任何方法一样,它可以返回任何类型的有效值string,包括null并且还可以抛出异常(在这种情况下,它根本不返回值)。

数学运算:所有表达式都会返回值或抛出异常。返回值可以是该类型的任何有效值(例如Int32,永远不能是null)。

于 2009-06-28T04:23:02.550 回答