CLR:如果构造函数失败,它总是会抛出异常吗?

发布于 2024-07-25 19:57:58 字数 685 浏览 6 评论 0原文

在Delphi中,如果在构造对象期间出现异常:将释放所有分配的内存并抛出异常。 例如,以下内容保证要么返回有效的Camera对象,要么抛出异常:

Camera c = new Camera();

您<从来没有必要检查结果变量是否为 null:

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")

In Delphi, if there was an exception during construction of an object: any allocated memory would be released and an exception would be thrown. For example, the following was guaranteed to either return a valid Camera object, or throw an exception:

Camera c = new Camera();

You never had to check the resulting variable for null:

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

Is the same true in the CLR?

And are there other syntatical constucts where a return value is guaranteed to either be valid, or throw an exception?

  • Creating structures (e.g. Rectangle)?
  • getting a member of an enumeration?
  • the result of Object.ToString()?
  • mathmatical operations?

In the case of performing math:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不喜欢何必死缠烂打 2024-08-01 19:57:58

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

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

至于您提到的其他情况

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

这个数学问题几乎本身就应该有答案。 一方面,对基本类型进行数学运算的结果永远不会为空。 但它仍然可能无效。 例如,下面的代码不会抛出异常,但结果是否有效很大程度上取决于您的具体场景

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

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

A constructor in .Net is guaranteed to return a non-null instance of the type of the object. Whether or not the instance is valid depends on the individual semantics of the type.

Exceptions thrown in a constructor will not be arbitrarily swallowed by the CLR (though user code can swallow them). The CLR will propagate an exception just like exceptions thrown in any other method and the objects will eventually be properly garbage collected.

As for the other cases you mentioned

  • Creating structures: Structures by definition can't ever be null. Exceptions thrown in the constructor will propagate normally
  • Getting a member of an enumeration: Enumerations are strutures / value types under the hood and also won't ever be null
  • the result of Object.ToString(): This can (and sadly will) be null. String is a reference type and it's perfectly legal to return null from a ToString override (please don't).
  • Mathematical operations: This depends heavily on both the overflow setting of your project and the particular type being used (integral vs. floating point).

The mathematical question almost deserves an answer on it's own. On one hand the result of a mathematical operation on primitive types won't ever be null. But it can still be invalid. For instance, the following code won't throw but whether or not the result is valid depends highly on your specific scenario

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

At this point f2 is a very specific float value that doesn't represent a real number. Is it valid? Depends on your use case.

半枫 2024-08-01 19:57:58

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

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

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

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

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

Yes. I'd like to put it this way (as fail might mean logical failure too): If a constructor doesn't throw an exception, the return value is guaranteed to be non-null so you never have to perform such a check.

Creating structures (e.g. Rectangle): A struct can't be null at all (Nullable types are considered completely different types, i.e. typeof(int?) != typeof(int)). Calling a constructor for a structure would either fail by throwing an exception or return an instance.

Getting a member of an enumeration: An enum is a just a set of constants. There's nothing like "getting a member at runtime." It's substituted at compile time.

The result of Object.ToString(): Like any method, it can return any valid value for string type which includes null and could also throw an exception (in which case, it doesn't return a value at all).

Mathematical operations: All expressions will return a value or throw an exception. The return value can be any valid value for that type (e.g. Int32 can never be null).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文