在另一个属性的设置器中设置另一个属性的值可以吗?

时间:2019-07-26 15:04:52

标签: c# oop setter

我有两个属性,第二个取决于第一个属性,我需要在类中同时拥有这两个属性,以便以后可以搜索它们。

我的情况是,每当属性A更新时,属性B也应自动更新,即每当有人更改Birthdate时,BirthDayAndMonth应自动更新。

public class Example
{
    private DateTime? _birthdate;

    public DateTime? Birthdate
    {
        get => _birthdate;

        set
        {
            _birthdate = value;
            if (_birthdate != null)
            {
                BirthDayAndMonth = GetAnnualBirthday(_birthdate.Value.Month, _birthdate.Value.Day);
            }
        }
    }

    public Date? BirthDayAndMonth { get; private set; }
}

我的代码是否违反任何OOPS原则?

2 个答案:

答案 0 :(得分:0)

否,您的代码没有违反任何OOP原则。但是,尽管这似乎在进行基本处理(显然,这取决于GetAnnualBirthday()的实际作用),但它可以变得更有效率。

我会懒惰地按如下所述对其进行处理。 Birthdate可以连续更改多次而无需调用GetAnnualBirthday,从而减​​少了处理量。如果调用BirthDayAndMonth时,将处理GetAnnualBirthday并保存结果以备以后使用。

public class Example
{
    private DateTime? _birthdate;
    private Date? _birthdateandmonth;

    public DateTime? Birthdate
    {
        get => _birthdate;

        set
        {
            _birthdate = value;
            _birthdateAndMonth = null; // force BirthDayAndMonth to be reprocessed
        }
    }

    public Date? BirthDayAndMonth
    {
        get
        {
            if (!Birthdate.HasValue)
                return null;
            if (!_birthdateandmonth.HasValue)
                _birthdateandmonth = GetAnnualBirthday(Birthdate.Value.Month, Birthdate.Value.Day);
            return _birthdateandmonth;
        }
    }
}

答案 1 :(得分:0)

  

我的代码是否违反任何OOPS原则?

否。

我在您的代码中看到的唯一问题是线程安全性。例如,两个线程正在设置Birthdate的值。一个将其设置为null,而另一个线程将其设置为非空值。

if (_birthdate != null)

是真的,然后是下一行,

BirthDayAndMonth = GetAnnualBirthday(_birthdate.Value.Month, _birthdate.Value.Day);

由于_birthdate现在为null而引发异常。

public class Example
{
    private DateTime? _birthdate;

    public DateTime? Birthdate
    {
        get => _birthdate;

        set
        {
            _birthdate = value;
            if (value != null)
            {
                BirthDayAndMonth = GetAnnualBirthday(value.Value.Month, value.Value.Day);
            }
        }
    }

    public Date? BirthDayAndMonth { get; private set; }
}

这保证了线程安全。