代码之家  ›  专栏  ›  技术社区  ›  Ian Boyd

clr:如果一个构造函数失败,它是否总是抛出一个异常?

  •  1
  • Ian Boyd  · 技术社区  · 15 年前

    在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")
    
    2 回复  |  直到 15 年前
        1
  •  3
  •   JaredPar    15 年前

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

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

    至于你提到的其他案件

    • 创建结构:根据定义,结构不能为空。构造函数中引发的异常将正常传播
    • 获取枚举的成员:枚举是引擎盖下的结构/值类型,并且永远不会为空。
    • object.toString()的结果:这可以(而且很遗憾)为空。字符串是引用类型,从ToString重写返回空值是完全合法的(请不要这样做)。
    • 数学运算:这在很大程度上取决于项目的溢出设置和所使用的特定类型(积分与浮点)。

    这个数学问题本身几乎值得一个答案。一方面,对基元类型进行数学运算的结果永远不会为空。但它仍然可能是无效的。例如,下面的代码不会抛出,但是结果是否有效取决于您的特定场景

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

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

        2
  •  1
  •   Mehrdad Afshari    15 年前

    对。我想这样说 失败 可能意味着 逻辑故障 太):如果构造函数不引发异常,则返回值保证为非- null 所以你不必做这种检查。

    创建结构(例如矩形):a struct 不能 无效的 根本( Nullable 类型被认为是完全不同的类型,即 typeof(int?) != typeof(int) )为结构调用构造函数将通过引发异常或返回实例而失败。

    获取枚举的成员:一个 enum 只是一组常量。没有什么比“在运行时获取成员”更重要的了,它在编译时被替换了。

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

    数学运算:所有表达式都将返回值或引发异常。返回值可以是该类型的任何有效值(例如 Int32 绝不可能 无效的 )