【问题标题】:Can anybody pinpoint the cause of this StackOverflowException?任何人都可以查明这个 StackOverflowException 的原因吗?
【发布时间】:2016-01-18 23:59:15
【问题描述】:

试图学习编程,但又一次失去了信心,因为我认为我已经内化了一个简单的概念,但似乎正在发生一些非同寻常的事情,或者它就在我的头上飞来飞去。

当我运行程序时,如果我通过将字符串分配给 FirstName 或 SecondName 来访问该属性,则会收到 StackOverFlowException

我的客户类别:

class Customer : ICustomer
{
    public string FirstName
    {
        get
        {
            return FirstName;
        }

        set
        {
            FirstName = value;
        }
    }

    public string fName
    {
        get
        {
            return fName;
        }

        set
        {
            fName = value;
        }
    }

    public string SecondName
    {
        get
        {
            return SecondName;
        }

        set
        {
            SecondName = value;
        }
    }

    public string sName
    {
        get
        {
            return sName;
        }

        set
        {
            sName = value;
        }
    }

    public int ID
    {
        get
        {
            return ID;
        }

        set
        {
            ID = value;
        }
    }

    public int mId
    {
        get
        {
            return mId;
        }

        set
        {
            mId = value;
        }
    }

    public int GetID()
    {
        return mId;
    }

    public void SetID(int id)
    {
        mId = ID;
    }

    public void SetName(string fName, string sName)
    {
        fName = FirstName;
        sName = SecondName;
    }
}

和主程序

class Program
{
    /// <summary>
    /// Create unique string code based off current date and time.
    /// </summary>
    /// <returns>code string</returns>
    static string generateUniqueCode()
    {
        string characters = "abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        string ticks = DateTime.UtcNow.Ticks.ToString();
        var code = "";
        for (var i = 0; i < characters.Length; i += 2)
        {
            if ((i + 2) <= ticks.Length)
            {
                var number = int.Parse(ticks.Substring(i, 2));
                if (number > characters.Length - 1)
                {
                    var one = double.Parse(number.ToString().Substring(0, 1));
                    var two = double.Parse(number.ToString().Substring(1, 1));
                    code += characters[Convert.ToInt32(one)];
                    code += characters[Convert.ToInt32(two)];
                }
                else
                    code += characters[number];
            }
        }
        return code;
    }

    /// <summary>
    /// Creates unique integer code based off current date and time.
    /// </summary>
    /// <returns>integer code</returns>
    static int generateUniqueCode(int seed)
    {
        string characters = "0123456789";

        Random randInt = new Random(seed);
        var ticks = randInt.Next();

        int code = 0;
        for (var i = 0; i < characters.Length; i += 2)
        {
            if ((i + 2) <= ticks)
            {
                var number = ticks;
                if (number > characters.Length - 1)
                {
                    var one = double.Parse(number.ToString().Substring(0, 1));
                    var two = double.Parse(number.ToString().Substring(1, 1));
                    code += characters[Convert.ToInt32(one)];
                    code += characters[Convert.ToInt32(two)];
                }
                else
                    code += characters[number];
            }
        }
        return code;
    }

    static void Main(string[] args)
    {
        Customer customer = new Customer();

        int generatedIntCode = generateUniqueCode(1);

        customer.FirstName = "Conor";
        customer.SecondName = "MacFirbhisigh";
        customer.SetID(generatedIntCode);
        Console.WriteLine("{0}, {1} {2}", customer.ID, customer.FirstName, customer.SecondName);

        //Console.ReadKey();
    }
}

【问题讨论】:

  • 你所有的属性都调用它自己,它调用它自己,它调用它自己......然后继续。
  • 另外,拥有一个公共属性以及只使用该属性的公共 get 和 set 方法也没有意义。
  • @SonerGönül 和 PatrickHofman 是正确的,但仅供参考,这些并不是您代码的唯一问题。 SetName 中的代码也是向后的(分配的方式是错误的)。
  • 供您以后参考,查找堆栈溢出原因的方法是 (1) 在调试器中运行程序,以及 (2) 检查 中间崩溃点的堆栈。当堆栈用完时,堆栈上的 last 东西只是不走运。堆栈中间的东西是做无限递归的东西。
  • 您能详细说明一下吗?有点知道堆栈是什么,但我不明白你的意思

标签: c# stack-overflow


【解决方案1】:

FirstName(以及所有其他人)的getter 和setter 中,您一遍又一遍地调用同一个属性。您创建的无限循环将导致StackOverflowException

如果您不想向属性添加自定义逻辑,只需使用自动实现的属性:

public string FirstName
{
    get;
    set;
}

如果您确实想自己实现该属性,创建自己的支持字段,它应该是这样的(这实际上与上面的代码生成的相同):

private string firstName; // backing field

public string FirstName
{
    get
    {
        return this.firstName; // return the backing field
    }
    set
    {
        this.firstName = value; // set the backing field
    }
}

【讨论】:

  • 为了教他们正确的做法,private string _firstName; public string FirstName { get { return _firstName;} set {_firstName = value;} }
  • 你为什么要这样做?这就是自动实现的属性所做的,对吧? @DrewJordan
  • 是的,当然是,我完全同意你的回答。我只是说他们显然不了解如何使用属性,而您的回答(虽然是正确的,我赞成)只是告诉他们“不要担心不理解它,而是这样做”。
  • 啊,好吧。谢谢@DrewJordan
  • 非常感谢您的快速回复。我看到它在很多教程/示例代码中都使用过,我发誓我以前使用过这种格式没有问题,尽管你已经解决了这个问题......最近有什么变化吗? @DrewJordan 这更有意义,非常感谢!
【解决方案2】:

你遗漏了一些重要的部分

首先,你总是需要声明你的变量,

public - 用于外部 get 和 set,因此不需要 get-set 方法。 private - get/set 方法是数据检索修改所必需的。

另外,请参阅 SetName 方法。

希望对你有帮助:p

这应该可以解决问题:

class Customer : ICustomer
{
    private string firstName;
    private string name;
    private string secondName;
    private string sName;
    private int iD;
    private int mId;

    public string FirstName
    {
        get
        {
            return firstName;
        }

        set
        {
            firstName = value;
        }
    }

    public string Name
    {
        get
        {
            return name;
        }

        set
        {
            name = value;
        }
    }

    public string SecondName
    {
        get
        {
            return secondName;
        }

        set
        {
            secondName = value;
        }
    }

    public string SName
    {
        get
        {
            return sName;
        }

        set
        {
            sName = value;
        }
    }

    public int ID
    {
        get
        {
            return iD;
        }

        set
        {
            iD = value;
        }
    }

    public int MId
    {
        get
        {
            return mId;
        }

        set
        {
            mId = value;
        }
    }

    public void SetName(string fName, string sName)
    {
        FirstName = fName;
        SecondName = sName ;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多