【问题标题】:Stack Overflow Exception C# [duplicate]堆栈溢出异常 C# [重复]
【发布时间】:2020-11-14 23:34:38
【问题描述】:

我遇到了这个错误

由于 *Exception 而终止进程。

错误来源来自这段代码

 internal class Record
{
    [Name("Name")]
    public string Name { get; set; }
    [Name("Principal")]
    public int Principal { get { return Math.Abs(Principal); } set {; } }

}

我搜索了错误并指出错误是由于recursive 而发生的。我认为我的Principal 方法不是递归方法。

【问题讨论】:

  • 它是递归的。当您尝试读取 Principal 属性时,您调用 get 访问器,get 访问器读取 Principal 属性,开始无限循环
  • 顺便说一句,您的主要方法也不是方法;这些东西(带有get/set)被称为“属性”。在与另一个开发人员交谈时使用确切的术语总是有帮助的,因为有一天你可能有一个带有属性和方法的类,如果你在指的是属性时说“方法正在崩溃”,你会造成很多混乱

标签: c# recursion math stack-overflow getter


【解决方案1】:

也许您想考虑以下之一:

internal class Record
{
    [Name("Name")]
    public string Name { get; set; }
    
    [Name("Principal")]
    public int Principal { get; set; }

    [Name("AbsPrincipal")]
    public int AbsPrincipal { get { return Math.Abs(Principal); } set; }

}
internal class Record
{
    [Name("Name")]
    public string Name { get; set; }
    
    [Name("Principal")]
    private int _principal = 0;
    public int Principal { 
      get => _principal; 
      set => _principal = Math.Abs(value); 
    }

}

任何属性或方法如果返回获取自己的值而没有任何阻止它的结果,就会溢出堆栈。正常工作的递归事物通常具有最终改变状态并停止递归的条件(不返回获取自己值的结果)

看看第一个:我们不让属性 math.abs 本身,我们让它 abs 别的东西 - 这不能递归,除非别的东西要返回第一件事(然后递归会翻转他们之间)

第二个可能更像你想要做的 - 我们再次吸收其他东西(支持变量)而不是属性本身防止递归溢出。在这个我abs在集合上,因为看起来你从来不想检索principal的非Abs值所以我们最好在存储它时abs它然后我们可以每次都检索它一百万次而不用abs..当然如果您需要对非 Abs'd 变量进行私有访问,您应该在获取时执行 abs.. 或者如果您知道您的用例将存储它一百万次并且只获取一次,再次执行 abs得到而不是集合。在大多数情况下,我期望的典型程序行为是设置的次数少于获取的次数,因此我们可以通过仔细选择何时执行 abs 来避免不必要的工作

【讨论】:

  • 我已经试过你的代码了。但是弹出一个错误。它说`抛出异常:CsvHelper.dll中的'CsvHelper.TypeConversion.TypeConverterException'。我应该如何处理这个问题
  • 可能您的 csv 中的“Principal”列包含无法转换为 int 的值;问题本身不是“我的代码”——我的代码所做的只是复制“你的代码”——你的代码也会遇到这样的错误。你可能需要做类似[Name("Principal")] private int _principal = 0; public string Principal { get => _principal.ToString(); set => _principal = Math.Abs(int.TryParse(value, out var i) ? i : 0); }
【解决方案2】:

正如史蒂夫建议的那样,您可以在获取 Principal 时调用 Principal 属性。因此是递归的。

你的意思是返回 Math.Abs​​(typeof(Principal));

【讨论】:

  • Typeof 返回一个 Type,你不能在上面使用 Abs
  • 好点。谢谢