【问题标题】:When I make conditions within properties, Do I have to make same conditions in Custom constructor again?当我在属性中创建条件时,我是否必须再次在自定义构造函数中创建相同的条件?
【发布时间】:2023-08-18 15:36:01
【问题描述】:

我的完整问题是:
当我在属性中创建条件时,我是否必须再次在自定义构造函数中创建相同的条件,或者我可以以某种方式使用属性自定义构造函数?

如果我有这样的代码:

class Program
{
    struct Student
    {
        private int _id;
        private string _name;
        private int _age;

        public int ID // Property
        {
            get
            {
                return _id;
            }
            set
            {
                if (value <= 0)
                {
                    Console.WriteLine("You cannot assign id less then 1");
                    Console.ReadLine();
                    Environment.Exit(0);
                }
                else
                {
                    _id = value;
                }
            }
        }

        public string NAME // Property
        {
            get
            {
                return _name;
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    _name = "No Name";
                }
                else
                {
                    _name = value;
                }
            }
        }

        public int AGE // Property
        {
            get
            {
                return _age;
            }
            set
            {
                if(value <= 0)
                {
                    Console.WriteLine("Your age cannot be less then 1 year.");
                    Console.ReadLine();
                    Environment.Exit(0);
                }
                else
                {
                    _age = value;
                }
            }
        }

        public Student(int initID, string initName, int initAge) // Defining custom constructor
        {
            if (initID <= 0)
            {
                Console.WriteLine("You cannot assign id less then 1");
                Console.ReadLine();
                Environment.Exit(0);
            }
            if (String.IsNullOrEmpty(initName))
            {
                _name = "No Name";
            }

            if (initAge <= 0)
            {
                Console.WriteLine("Your age cannot be less then 1 year.");
                Console.ReadLine();
                Environment.Exit(0);
            }
            _id = initID;
            _name = initName;
            _age = initAge;
        }

        public void Status() // struct member - method
        {
            Console.WriteLine("ID: {0}", _id);
            Console.WriteLine($"Name: {_name}");
            Console.WriteLine($"Age: {_age}\n");
        }


    }

    static void Main(string[] args)
    {
        Student s1 = new Student(1, "James", 10);
        s1.Status(); 
        Console.ReadLine();
    }
}

如您所见,我在属性中设置了一些条件,例如 ID 不能为 0 且小于 0,但是当我想使用自定义构造函数时,我必须再次设置此条件。这是唯一的方法如何做到这一点?还是其他方式?

自定义构造函数是否与封装一起使用?当你有属性时?

感谢您的回答。 :)

【问题讨论】:

  • 您的第一个问题是您使用的是struct 而不是class。你应该有一个很好的理由这样做。您很少需要使用struct

标签: c# if-statement struct properties encapsulation


【解决方案1】:

首先:使用class 而不是struct,只要你没有很好的理由使用struct

这是使用方法而不是公共属性的一个很好的例子。

仅包括年龄的简短示例以显示我在说什么。

public class Student
{
    private int _age = 1;

    public Student(int initAge)
    {
        SetAge(initAge);
    }

    public void SetAge(int age)
    {
        if (age <= 0)
        {
            Console.WriteLine("Your age cannot be less then 1 year.");
            Console.ReadLine();
            Environment.Exit(0);
        }
        else
        {
            _age = age;
        }
    }

    public int GetAge()
    {
        return _age;
    }
}

当您必须在分配值之前进行检查时,我建议您使用设置和获取值的方法。干净多了。

你可以像这样扩展你的 set 方法

public bool TrySetAge(int age)

并返回真或假。可以设置值时为真,否则为假。

【讨论】:

    【解决方案2】:

    您无需重新发明完整的逻辑。您可以在构造函数中调用属性设置器并依赖其验证逻辑:

    public Student(int initID, string initName, int initAge) // Defining custom constructor
    {
        this.ID = unitID;
        this.NAME = initName;
        this.AGE = initAge;
    }
    

    现在,当任何参数错误时,属性设置器会报错,无需再次在构造函数中检查。

    顺便说一句,我不会因为参数错误而退出应用程序。但是,您可以抛出 ArgumentException 并在调用代码中捕获它,或者使用 @Mighty Badaboom 的方法和 TryParse-pattern。

    【讨论】:

      【解决方案3】:

      除非您在构造函数中的条件不同,否则没有理由重复设置器代码。

      public Student(int initID, string initName, int initAge) // Defining custom constructor
      {
              ID = initID;
              NAME = initName;
              AGE = initAge;
      }
      

      或者您可以删除构造函数并改为使用公共属性的标准语法。

      var student = new Student
      {
          ID = id,
          NAME = name,
          AGE = age
      };
      

      【讨论】: