【问题标题】:Determine string assignment operator exception that may occur判断可能出现的字符串赋值运算符异常
【发布时间】:2019-10-08 16:44:35
【问题描述】:

我目前正在学习 c# 中 try、switch、异常的正确用法,我问自己是否可以在 = 运算符处引发异常。

我搜索了一些并找到了https://referencesource.microsoft.com/#mscorlib/system/string.cs 这应该是字符串类的实现,但我在此代码中找不到 =operator 定义。我在哪里可以在我自己的系统上找到我自己的 string.cs 类实现?我只找到了这个在线版本。

string line = Console.ReadLine();
//Console.ReadLine() can throw ArgumentOutOfRangeException,
//OutOfMemoryException or IOException.
//but what can the = operator throw?

//what will happen in the following code?
string l = "Very Very extreme long long text";

如何处理 100% 正确?

【问题讨论】:

  • = 不是可重载的运算符。 = 运算符可以导致发生隐式用户定义的转换,这可能会引发异常,但这并不完全相同。
  • 内部如何定义=操作符?系统知道什么字符串 s = "str";意思是
  • = 运算符总是要么只是将一个值复制到一个变量,要么调用一个属性设置器或一个索引器。它不是基于每种类型定义的。
  • 好的。我找到了stackoverflow.com/questions/3436101/create-custom-string-class。您可以使用隐式对话来做到这一点,但在许多情况下这不是一个好主意。

标签: c# string exception crash operator-keyword


【解决方案1】:

理论上,你不能从你写的代码中得到异常。

但如果出现某些 I/O 或内核错误,Console.ReadLine 可能会引发异常。

对于字符串分配,我认为除了内存不足、内存溢出或进程损坏之外,不会发生其他事情,在这种情况下,您将失去对将崩溃的应用程序的所有控制,也许您可​​以得到一个蓝屏或类似的东西。如今,在个人电脑上甚至在智能手机上,这将是非常罕见的。也许在一个迷你嵌入式系统上。

你不需要尝试捕捉这些东西。

不过要谨慎一点,你可以试着去接作业,但这是一种损失。

【讨论】:

    【解决方案2】:

    赋值本身不能抛出异常,但所涉及的转换、索引器、属性 getter 和 setter 或成员访问可以。但这很可能意味着您有一个必须修复的编程错误。

    您应该只对真正的运行时问题进行异常处理。主要是与 I/O 相关的东西,但也有设计用于在某些条件下抛出的 API。不要为编程错误做异常处理!

    赋值运算符不能重载。


    一个编程错误的例子是

    int[] array = GetArray();
    for (int i = 1; i <= array.Length; i++) {
        Console.WriteLine(array[i]);
    }
    

    它会抛出一个IndexOutOfBoundsException,因为索引范围从0array.Length - 1

    正确代码:

    int[] array = GetArray();
    for (int i = 0; i < array.Length; i++) { // Note: starting at 0 and using < instead of <=
        Console.WriteLine(array[i]);
    }
    

    使用正确代码可能会出现异常的示例是

    File.WriteAllText(path, contents);
    

    文件可能被另一个应用程序锁定,或者驱动器未附加,或者您可能没有足够的权限等。

    这里try-catch 是合适的。

    【讨论】:

    • 感谢您的回答!编程错误是什么意思?如果我的程序需要一个大列表并尝试从我的系统分配我的系统没有的新内存怎么办。将抛出我应该捕获的 OutofMemoryException。字符串类内部的=操作符是怎么定义的?
    • 编程错误是例如索引超出范围或收到NullReferenceException。因为那时,您的代码不正确。 OutOfMemoryException 是致命的。您对此无能为力,例如,除非它是由无休止的递归引起的。但是,您又遇到了编程错误。赋值不会生成OutOfMemoryException,但对象创建可以:x = new SomeObject();
    • 为什么 OutOfMemoryException 如此致命?我可以抓住它并处理它。
    • 嗯,有些情况下你可以抓住它。例如,如果您尝试创建一个巨大的数组,您可能会得到一个OutOfMemoryException。然后尝试创建一个较小的。但通常情况下,您将没有足够的内存来执行您正在尝试做的事情。所以这主要是一种无法治愈的疾病。
    • 大数组的例子很好。我也有同样的想法。所以我创建了一个导致 OutOfMemoryException 的巨大数组,然后我捕获了这些异常并删除了这个数组以拥有内存,以便创建一个不会导致 OutOfMemoryException 的更小的数组。为什么说这是个问题?
    猜你喜欢
    • 2016-04-01
    • 2010-12-17
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 2015-08-23
    • 2014-02-07
    相关资源
    最近更新 更多