【问题标题】:Do while loop in property causes stack在属性中执行while循环会导致堆栈
【发布时间】:2012-10-13 20:00:17
【问题描述】:

我最近开始尝试自学 C#,这在很大程度上是初学者尝试在属性中使用业务规则的尝试,在我的例子中是 FurColor。当我运行下面的程序时,我得到一个NullReferenceException。有人可以帮我找到这个错误的原因吗?异常发生在第 15 行

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _10_23_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("programming practice!");
            Dog d = new Dog();
            Console.Write("what color is your dog: ");
            d.FurColor = Console.ReadLine();
            Console.WriteLine("the color of your dog is {0}", d.FurColor);
        }
    }
    class Dog
    {
        private string furColor;
        private string petName;
        private int tagNum;

        public Dog() { }

        public Dog(string color, string name, int tagID)
        {
            furColor = color;
            petName = name;
            tagNum = tagID;
        }
        //properties
        public string FurColor
        {
            get { return furColor; }
            set {                    
                    do
                    {
                        Console.Write("enter in a viable color type: ");
                    }
                    while (furColor.Length > 10);
                    furColor = value;
                }
        }
        public string Name
        {
            get { return petName; }
            set { petName = value; }
        }
        public int TagNum
        {
            get { return tagNum; }
            set { tagNum = value; }
        }

    }
}

【问题讨论】:

  • 哪一行出现异常?
  • 您没有在 FurColor 的循环中分配任何内容。

标签: c# exception null


【解决方案1】:

一旦更正,您将得到一个无限循环。

旁注:您不应在属性的 Set 子句中要求输入。

您应该更喜欢要求输入的成员函数,检查它是否有效,然后设置颜色。

在你的狗类中添加一个如下所示的函数:

public void setFurColor()
{
    string color = string.Empty;
    do
    {
        Console.Write("what color is your dog: ");
        color = Console.ReadLine();
    }while ( ! string.IsNullOrEmpty(color)  && bleh.Length < 10);
    this.furColor = color;
}

【讨论】:

  • 我会记住这一点。谢谢。这是我虚构的场景突然出现在我脑海中的。
  • 主要问题是你没有机制来重新分配循环中的值,所以这会产生一个无限循环。
  • 我的印象是不应该使用 getter 或 setter 方法,而应该使用属性。如果有简单的业务逻辑而不是自动属性,是否应该使用 getter 和 setter 方法?
  • 这取决于上下文。在您的示例中,您要求用户输入以设置值,此逻辑不应成为属性的一部分,因为当您想在不同的上下文中重用对象时会产生问题。
  • 有趣。谢谢,我会在学习时牢记这些事情。
【解决方案2】:

在访问其 furColor.Length 之前检查 furColor 是否为 null

【讨论】:

    【解决方案3】:

    您的代码没有任何意义,但没关系,因为您正在学习如何编写代码。 :)

    所以 - 我猜你想存储 furColor 仅当用户输入的字符串长度大于 10 个字符时。如果是这样,您应该在将值分配给对象属性之前检查字符串是否正确,如果不是,则在类属性代码之外循环显示警告消息。

    【讨论】:

    • 当我阅读参考书并查看他们的程序时,这在世界上都是有意义的。当我试图自己把一些东西放在一起而不看任何东西时......这是一个不同的故事
    • 嗯,一开始就是这种感觉。一旦你尝试失败大约 100 次,它就会解决:)
    【解决方案4】:

    要使您拥有的代码工作:您正在访问furColor.Length 而没有设置毛皮......此时它什么都不是(null)。你应该检查value

    此外,这不是您希望在属性的 setter 中使用的那种逻辑。您的设置器不应该输出读数值,它应该简单地设置属性,因为这就是它的用途。将 while 循环放在 main 中。

    【讨论】:

      【解决方案5】:

      您正在使用 Dog 的公共无参数构造函数

      public Dog() { }
      

      此构造函数未设置 furColor 字段,因此在您的 Dog 实例中它将为空。

      这意味着访问下一行中furColor 字段的Length 属性将引发NullReferenceException。

      while (furColor.Length > 10);
      

      解决此异常的一种方法是在无参数构造函数中为这些字段设置默认值,如下所示:

      public Dog() : this("brown", "Fido", default(int))
      {
      }
      

      或者,您可以:

      • 使用带参数的构造函数,为furColor 传入一个非空值。
      • 检查 FurColor 属性设置器中的 null。
      • 在声明的位置设置field

      【讨论】:

        【解决方案6】:

        您的furColor 变量需要在访问其长度之前分配和/或检查是否为空。由于您使用的是默认构造函数,因此您永远不会分配给 furColor 字符串。 你会想从默认调用你的其他构造函数:

        public Dog() : this("defaultColor", "defaultName", default(int)) {}
        

        话虽如此,在属性中要求用户输入并不是一种好的编程习惯,并且您最终会在属性中出现无限循环。

        【讨论】:

          猜你喜欢
          • 2013-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-21
          • 1970-01-01
          相关资源
          最近更新 更多