【发布时间】:2009-10-31 13:01:45
【问题描述】:
为什么DateTime 是一个结构而不是一个可继承的类?
(我希望能够覆盖 ToString() 方法,但我不能。)
【问题讨论】:
为什么DateTime 是一个结构而不是一个可继承的类?
(我希望能够覆盖 ToString() 方法,但我不能。)
【问题讨论】:
我相信它是一个结构体,因为结构体是值类型,而类是引用类型。 DateTime 中的实际数据是一个长整数。如果它是一个类,则每次创建一个新对象时,都会在堆上分配 8 个字节,在堆栈上为指针分配另外 8 个字节。因此,通过将 DateTime 设为结构,它有效地将内存需求减少了一半。
您可以在this question找到更多信息。
【讨论】:
您可以为此使用扩展方法: 声明扩展:
public static class DateTimeExtensions
{
public static string ToStringFormatted(this DateTime date)
{
return date.ToString("{d}");
}
}
使用扩展:
using DateTimeExtensions;
...
var d = new DateTime();
System.Diagnostics.Debug.WriteLine(d.ToStringFormatted());
这样您就可以简单地实现您自己在 DateTime 上使用的方法。这样,它就可以轻松地在您的解决方案中随处使用。您唯一需要做的就是使用命名空间。
【讨论】:
可能是因为它被视为一种小型、简单且不可变的数据结构,很像整数或小数。在这些条件下使其成为结构使得使用 DateTime 非常有效。如果它已经成为一个类,那么这种效率优势就会丧失,因为每次创建新的 DateTime 时都需要分配内存。
此外,您能想出多少种 DateTime 的变体形式? (忽略您想到的替代 ToString 实现。)它不完全是一种会引起多态性的类型。
请注意,对于您的 DateTimes 使用不同的格式化策略,正如我认为您想要的那样,您最好查看一种不同的格式化方式,而不仅仅是使用 ToString。如果您查看 MSDN 中的 ICustomFormatter 接口,您将了解如何插入 String.Format 管道以覆盖格式,而无需对现有类型进行子集化。
【讨论】:
因为它是一个单点。它没有多条数据。在引擎盖下它由一个长表示。
【讨论】:
DateTime 的大小很小。因此,为此在堆上分配内存效率不高。
在赋值时复制它是合乎逻辑的,而不是创建对同一对象的引用,特别是因为它是不可变的。对其进行操作也是如此(Add、Substract等)
它必须可转换为相应的 COM 结构。
如果您想要自定义格式,您可以像 here 所示那样实现它。
【讨论】:
如果您想了解有关系统类和结构的更多信息,请下载免费的 .NET 反射器 (http://www.red-gate.com/products/reflector/)。
无论如何,如果您想覆盖 DateTime 的格式化方式,请提供您自己的 IFormatProvider。使用 .NET Reflector 了解 DateTimeFormatInfo 是如何实现的,然后自己实现。
【讨论】:
仅仅因为它是一个结构体(或者即使它是一个密封类),这并不意味着它是路的尽头。你可以用composition解决这个问题,而不是继承。这是一个“对象化” DateTime 类的示例:
public class MyDateTime
{
DateTime? value;
public MyDateTime()
{
this.Value = DateTime.Now;
}
public MyDateTime(DateTime? dateTime)
{
this.Value = dateTime;
}
public override String ToString()
{
if (this.Value != null)
{
return this.Value.Value.Month.ToString() + " my favorite time of the year";
}
return null;
}
public System.DateTime? Value
{
get { return this.value; }
set { this.value = value; }
}
}
【讨论】: