如何通过“obj.MyDate.AddDays”创建支持变异的类?

时间:2012-03-02 00:41:37

标签: c# class datetime properties struct

我想创建一个由DateTime结构支持的属性,但是,因为结构是值类型,MyClass.MyDate.AddDays(1)不能按以下类的预期工作:

public class MyClass
{
  public DateTime MyDate { get; set; }
}

期望的行为是让DateTime属性增加一天,但在我的示例中,属性保持它的初始值。我可以使用代码MyClass.MyDate = MyClass.DateTime.AddDays(1)获得相同的结果,但这是违反直觉的。我理解为什么这不起作用,但我不确定解决它的最佳方法。

创建MyDate属性的公认方法是什么,以便像AddDays()这样的公开DateTime方法更新实例变量?

5 个答案:

答案 0 :(得分:3)

MyClass.MyDate = MyClass.DateTime.AddDays(1)

这是结构的标准行为。所有符合标准的结构都是不可变的,除非有充分理由。

如果您对上述语法确实有问题,我建议这样:

public class MyClass
{
    public DateTime MyDate { get; set; }

    public void AddDays(double days)
    {
        this.MyDate = this.MyDate.AddDays(days);
    }
}

答案 1 :(得分:1)

AddDays和其他方法永远不会更新字段或属性的内容,因为它们不会更新值本身。相反,他们通过调整返回一个新值。

您可以使用以下代码轻松测试:

DateTime dt = DateTime.Today;
Debug.WriteLine(dt);
dt.AddDays(1);
Debug.WriteLine(dt);

您将获得两次打印的相同日期。你通过财产这样做的事实与这里的问题无关。

如果你需要进行方法调用,我会考虑直接将它们添加到你的类中。

例如,您可以这样称呼:

mc.AddDays(1);

而不是这样做:

mc.MyDate = mc.MyDate.AddDays(1);

但是,我会认真考虑不要这样做。它为你自己的班级增加了很多东西。

相反,我可能会考虑而不是节省的时间,因为省钱,并把它们放到购买ReSharper,因为它有检查会告诉你{{1}没有效果(至少对于它知道的情况,比如DateTime。)

答案 2 :(得分:0)

您已经显示了可接受的方法 - 因为DateTime是不可变的,因此再次将AddDays()的结果分配给该属性。 DateTime不可变的事实实际上会在这里保存你的培根,因为如果不是这样你就会被再次分配回属性,这当然不会有预期结果,因为你正在改变一个无处可去的副本。

以“直观”方式执行此操作的唯一方法是使用装饰器类来包装DateTime,然后可以按照您希望的方式安全地修改它。我不建议这样做,因为在我看来这增加了更多的复杂性。

答案 3 :(得分:0)

我想指出你的问题与DateTime是结构无关。 ' String is not struct, but it's immutable the same way DateTime`是如此MyString.Substring(1,2)不会给你你所期望的。

另外我的观点是,对于有经验的开发人员来说,这种行为没有任何反直觉。知道DateTime是不可变的,我永远不会想到MyClass.MyDate.AddDays(1)应该改变属性值。为什么会这样?

最后我不认为你有一个需要解决的问题,你只需要对c#和.net的工作方式感到更舒服

答案 4 :(得分:0)

MyClass myClass = new MyClass() { MyDate = DateTime.Now };
myClass.MyDate += new TimeSpan(1, 0, 0, 0);