我想创建一个由DateTime
结构支持的属性,但是,因为结构是值类型,MyClass.MyDate.AddDays(1)
不能按以下类的预期工作:
public class MyClass
{
public DateTime MyDate { get; set; }
}
期望的行为是让DateTime属性增加一天,但在我的示例中,属性保持它的初始值。我可以使用代码MyClass.MyDate = MyClass.DateTime.AddDays(1)
获得相同的结果,但这是违反直觉的。我理解为什么这不起作用,但我不确定解决它的最佳方法。
创建MyDate属性的公认方法是什么,以便像AddDays()这样的公开DateTime方法更新实例变量?
答案 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);