【问题标题】:c# stackoverflow for some strange reason in elementary codec#stackoverflow在基本代码中出于某种奇怪的原因
【发布时间】:2013-01-15 23:06:54
【问题描述】:
  • 我有一个 RoundedSum 对象,它主要检查产品的价格和一个整数和到数据库中。
  • 我有一个 UnRoundedSum 对象,它基本上继承了 RoundedSum 并覆盖了 checkinsum 函数,并将与最接近的整数的差值检查为未计入的
  • UnRoundedSum 调用 base 的 checkinsum(productid,int) 来检查 数据库中的价格值这是我的命名空间 SumRounding,它有 2 课程

namespace DatabasePricing.SumRounding
{
    public class Roundedsum
    {
        public void checkinsum(int productid,int sum)
        {
            //Checks in price in the price table
            //dbobject("price",productid,sum);
            int temp_int = sum;    
        }
    }

    public class UnRoundedSum : Roundedsum
    {
        public void checkinsum(int productid,float sum)
        {
            //Since the sum is a float it will check the difference 
            //into unroundedsum table in the database 
            int intsum = (int)sum;
            float tempfloat = sum - intsum;
            //Check this remaining float into the database under unaccounted
            // dbobject("unroundedsum",productid,tempfloat);                
            //Now call the integer checksum with the integer value
            checkinsum(productid,intsum);
        }
    }
}

让我们假设我现在创建了一个用于测试 rite 的主要函数,因为它在我的项目中不起作用。嗯,这就像上述类的测试对象。

using DatabasePricing.SumRounding;
    namespace DatabasePricing
    {
        class testingrounding
        {
            static void Main() { 
            int product_id = 1;
            float float_value = 1.1f;
            UnRoundedSum obj1 = new UnRoundedSum();
            //This call produces StackOverflow Exception
            obj1.checkinsum(1, float_value);
            int price = 200;
            //I tried with integer value to test RoundedSum object
            //it is still throwing an exception
            //This call also produces StackOverflow Exception
            obj1.checkinsum(1, price);        
            }
        }
    }


当我尝试调试时,它总是在引发 StackOverflow 错误之前被 checkinsum() 捕获。当我尝试调试时,即使在执行后它也会返回到 checkinsum()。由于某种原因,它不断回来。我不知道会出什么问题。

【问题讨论】:

  • 这很可能是递归调用checkinsum引起的
  • 在执行对 UnRoundedSum.checkinsum 的调用时,它会在什么时候停止调用自己?由于没有终止案例,因此您很快就会填充调用堆栈。顺便说一句,因为这是一个尾调用,所以相同的代码很可能会进入无限循环,而不会导致 x64 抖动上的 stackoverflow
  • 方法checkinsum是递归的。 您应该使用 Visual Studio 来帮助定位此类问题。
  • C++没有什么,所以请不要标记它是C++。
  • 我想我有点困惑,因为我已经@it 很长时间了。也许你们所有人都看对了。让我更好地理解你所有的 cmets。谢谢你的帮助..

标签: c# sql exception stack-overflow


【解决方案1】:

checkinsum 中有一个无限递归调用。

您可能想在UnRoundedSum.checkinsum 中致电base.checkinsum

public void checkinsum(int productid,float sum)
{
    //Since the sum is a float it will check the difference 
    //into unroundedsum table in the database 
    int intsum = (int)sum;
    float tempfloat = sum - intsum;
    //Check this remaining float into the database under unaccounted
    // dbobject("unroundedsum",productid,tempfloat);                
    //Now call the integer checksum with the integer value
    base.checkinsum(productid,intsum);
}

【讨论】:

  • 好吧,我之前尝试过并删除了它。但是当我调用 obj1.checkinsum(1,20);它仍然会因为某种原因调用 UnRoundedSum.checkinsum(1,20) 而不是调用 RoundedSum.checkinsum(1,20) .. 因为这个我在数据库中有一个额外的 0 值条目.. 是的 base.checkinsum (productid,intsum) 它可以工作,但它给了我一个额外的价值。你能帮我理解为什么会这样吗..
【解决方案2】:
    checkinsum(productid,intsum);

应该是

    base.checkinsum(productid,intsum);

在 UnRoundedSum 类中

编辑:解释,没有基础。 (就是去基类,然后调用那里的方法)它会在UnRoundedSum中调用自己,所以这将是一个无限循环,会导致stackoverflow

EDIT2:

看完你的 cmets 我想你想要这个:

public class sum
{
    public void checkinsum(int productid, float sum)
    {
        //Since the sum is a float it will check the difference 
        //into unroundedsum table in the database 
        int intsum = (int)sum;
        float tempfloat = sum - intsum;
        //Check this remaining float into the database under unaccounted
        // dbobject("unroundedsum",productid,tempfloat);                
        //Now call the integer checksum with the integer value
    }
    public void checkinsum(int productid, int sum)
    {
        //Checks in price in the price table
        //dbobject("price",productid,sum);
        int temp_int = sum;
    }
}

然后它将执行您想要的方法,或者它是 int int 或 int float。

【讨论】:

  • 好吧,我之前尝试过并删除了它。但是当我调用 obj1.checkinsum(1,20);它仍然会因为某种原因调用 UnRoundedSum.checkinsum(1,20) 而不是调用 RoundedSum.checkinsum(1,20) .. 因为这个我在数据库中有一个额外的 0 值条目.. 是的 base.checkinsum (productid,intsum) 它可以工作,但它给了我一个额外的价值。你能帮我理解为什么会这样吗..
  • checkinsum(int,int) 仅在我的基础中定义。我用派生的 checkinsum(int,float) 重载了它,所以我可以将四舍五入的数字发送到一个未计入的表,并将真正的 int 发送到 pricevalue 表..
  • c# 如果需要,会自动将浮点数转换为 Int。所以它也不会出错。
【解决方案3】:

C# 标准规定“如果派生类中的任何方法适用,则基类中的方法不是候选方法”。换句话说,checkinsum(int,float) 在调用 checkinsum(1,1) 时总是优先于 base.checkinsum(int,int),因为前者在派生类中,而 C# 允许将 int 隐式转换为 float

见:http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

【讨论】:

  • 你确定。你也有我的支持。谢谢您的帮助。我现在明白是什么导致我的数据库中有这么多 0 个条目。
  • 感谢您的解释和文章链接。它现在对我有用。
  • 无论如何我可以防止这种情况发生。如 func(int) 基类和 func(float) 派生类不同。所以当我调用派生类对象的 func(int) 时,它不应该匹配 func(float) 派生类的签名并转到 func(int) 基类。我如何使用设计防止这种情况发生?是只有int和float还是有其他例子2?只是好奇,因为你似乎完全掌握了我的问题。
  • @user1974729:C# 只会在内置数据类型(int、float、double、char 等)和派生类(即从 UnRoundedSum 到 RoundedSum)之间隐式转换。获得所需内容的最佳方法是显式引用 base.checkinsum 或选择其他方法名称,例如 checkinsum_float
  • @user1974729:在我看来,我认为你应该重新考虑你对面向对象编程的使用。 UnRoundedSum 作为RoundedSum 的单独类(不继承)可能会更好,可能具有共享接口。
猜你喜欢
  • 1970-01-01
  • 2022-11-27
  • 2013-03-16
  • 2017-03-16
  • 2014-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多