【问题标题】:C# constructors - setting second attributeC# 构造函数 - 设置第二个属性
【发布时间】:2011-08-12 11:01:02
【问题描述】:

我有这门课:

public class CalendarData_Day
{
    public DateTime Date { get; set; }
    public DayType TypeOfDay { get; set; }
    public bool Choose { get; set; }

    public CalendarData_Day(DateTime datum) : this(datum, DayType.Normal, true)
    {
    }

    public CalendarData_Day(DateTime datum, DayType typDne) : this(datum, typDne, true)
    {
    }

    public CalendarData_Day(DateTime datum, DayType typDne, bool vybran)
    {
        this.Date = datum;
        this.TypeOfDay = typDne;
        this.Choose = vybran;
    }
}

我想在第二个构造函数中检查 DayType 是否是 Weekend,如果它不是发送到选择 true 而是 false。有人知道我该怎么做吗? 我知道我可以添加到最后一个构造函数 if 并检查,但它似乎不适合我。我认为有更好的方法我认为我应该以其他方式进行,或者在最后一个构造函数中可以吗:

if (TypeOfDay == DayType.Weekend)
    this.Choose = false;

我知道它有效,但我不知道它是正确的方式。

编辑: 对不起,我没有解释一切。有超过 2 个 DayTypes,假设有 Holiday,Work,... 我希望用户可以使用第二个构造函数调用类,如果 DayType 是 Weekend 或 Holiday,那么 Choose 必须为 false,但如果它是 Normal 或工作它应该是真的,或者用户必须使用最后一个构造函数并将 DayType 设置为工作并选择为假。好复杂,不好意思第一次写。

【问题讨论】:

    标签: c# class constructor


    【解决方案1】:

    根据参数传递链式构造函数参数会更好:

    public CalendarData_Day(DateTime datum, DayType typDne)
        : this(datum, typDne, typeDne != DayType.Weekend)
    {        
    }
    

    这样您就不需要设置属性两次 - 一次设置为某种默认值,然后根据您已知的信息进行修复。

    我会亲自将参数名称从 typDne 更改为 dayType 或类似名称。

    编辑:我刚刚看到您正在考虑将测试放入 last 构造函数而不是 second 构造函数。我希望调用者为vybran 提供的值按原样接受,而不是有条件地忽略。您只描述希望 second 构造函数检查DayType == Weekend - 而不是最后一个构造函数 - 所以只有第二个构造函数应该改变。

    编辑:如果 Choose must 对于周末或假期为假,那么我会在最后一个构造函数中强制,但选择 value在第二个构造函数中:

    public CalendarData_Day(DateTime datum, DayType typDne)
        : this(datum, typDne,
               typeDne != DayType.Weekend && typeDne != DayType.Holiday)
    {        
    }
    
    public CalendarData_Day(DateTime datum, DayType typDne, bool vybran)
    {
        if (vybran && (typeDne == DayType.Weekend || typeDne == DayType.Holiday))
        {
            throw new ArgumentException(
               "vybran cannot be true for holiday or weekend dates", "vybran");
        }
        this.Date = datum;
        this.TypeOfDay = typDne;
        this.Choose = vybran;
    }
    

    【讨论】:

    • 我喜欢你的解决方案,但很抱歉我忘了提到它不仅仅是 DayType.Weekend 和 Normal,它可能是更多类型,所以我认为我必须在最后一个构造函数中设置属性两次。
    • @Bibo:为什么?我的方法完全按照您的描述进行 - 如果 typeDne 是 Weekend,则选择将为 false,否则为 true……再说一次,如果用户直接调用最后一个构造函数,为什么要覆盖用户传入的内容?如果真的是您的意图,请编辑您的问题以澄清它。想想如果用户直接调用new CalendarData_Day(date, DayType.Weekend, true)会发生什么
    • 周末应该永远是假的,但你是对的,它在某些情况下会造成混乱,所以我编辑了我的帖子。
    • @Bibo:我已经编辑了我的答案 - 请参阅第二部分。请注意“选择默认值”与“强制值的有效性”的区别。
    【解决方案2】:

    在构造函数中验证参数是完全可以的。

    虽然您应该确保如果条件为假,您的代码仍然可以按预期工作:

    if (TypeOfDay == DayType.Weekend)
    {
       this.Choose = false;
    }
    else
    {
       this.Choose = vybran;
    }
    

    如果传入的参数完全错误,你可以考虑抛出ArgumentException

    【讨论】:

    • 通常,当我看到一个“如果”时,两个主体中的所有变化都是以相同方式使用的值,我会使用条件表达式或其他表达式来给出正确的答案。在这种情况下:this.Choose = TypeOfDay != DayType.Weekend;。如果您想让比较更清楚,请使用括号。
    • @Jon - 同意,除非您希望在测试失败时实际传入的值。你的版本和我的版本不同。
    • 哦,我实际上误读了这个问题 - 我认为测试是在 second 构造函数中......虽然只有 description讨论调用第二个构造函数时行为的变化。奇怪的。已编辑我的答案以突出显示这一点。
    • @Oded: :) 我距离周末开始只有 15 分钟。那是我的借口!
    【解决方案3】:

    如果您的构造函数之一具有非常广泛的逻辑,您可能会从调用私有构造函数的静态构造函数中受益。

    class MyClass
    {
      private MyClass(...)
      {
    
      }
      public static MyClass CreateMyClassWithValidation(...)
      {
        if(....)
          return new MyClass(...);
      } 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-16
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多