【问题标题】:Why is DateTime a structure in .Net?为什么 DateTime 是 .Net 中的结构?
【发布时间】:2009-10-31 13:01:45
【问题描述】:

为什么DateTime 是一个结构而不是一个可继承的类?

(我希望能够覆盖 ToString() 方法,但我不能。)

【问题讨论】:

    标签: .net datetime structure


    【解决方案1】:

    我相信它是一个结构体,因为结构体是值类型,而类是引用类型。 DateTime 中的实际数据是一个长整数。如果它是一个类,则每次创建一个新对象时,都会在堆上分配 8 个字节,在堆栈上为指针分配另外 8 个字节。因此,通过将 DateTime 设为结构,它有效地将内存需求减少了一半。

    您可以在this question找到更多信息。

    【讨论】:

    • 很好的解释
    【解决方案2】:

    您可以为此使用扩展方法: 声明扩展:

    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 上使用的方法。这样,它就可以轻松地在您的解决方案中随处使用。您唯一需要做的就是使用命名空间。

    参考:Extension Methods (c#)

    【讨论】:

    • 是的,但请不要将其命名为“ToString2”! :)
    • 当然,这只是一个例子... ;)
    【解决方案3】:

    可能是因为它被视为一种小型、简单且不可变的数据结构,很像整数或小数。在这些条件下使其成为结构使得使用 DateTime 非常有效。如果它已经成为一个类,那么这种效率优势就会丧失,因为每次创建新的 DateTime 时都需要分配内存。

    此外,您能想出多少种 DateTime 的变体形式? (忽略您想到的替代 ToString 实现。)它不完全是一种会引起多态性的类型。

    请注意,对于您的 DateTimes 使用不同的格式化策略,正如我认为您想要的那样,您最好查看一种不同的格式化方式,而不仅仅是使用 ToString。如果您查看 MSDN 中的 ICustomFormatter 接口,您将了解如何插入 String.Format 管道以覆盖格式,而无需对现有类型进行子集化。

    【讨论】:

      【解决方案4】:

      因为它是一个单点。它没有多条数据。在引擎盖下它由一个长表示。

      【讨论】:

      • 我没有投反对票,但从你的回答来看,结构总是包含一个“数据片段”,这是 DateTime 是结构的唯一原因。您没有提到结构和类之间的性能差异,我认为应该将其包含在问题的答案中。
      【解决方案5】:
      • DateTime 的大小很小。因此,为此在堆上分配内存效率不高。

      • 在赋值时复制它是合乎逻辑的,而不是创建对同一对象的引用,特别是因为它是不可变的。对其进行操作也是如此(AddSubstract等)

      • 它必须可转换为相应的 COM 结构。

      如果您想要自定义格式,您可以像 here 所示那样实现它。

      【讨论】:

        【解决方案6】:

        如果您想了解有关系统类和结构的更多信息,请下载免费的 .NET 反射器 (http://www.red-gate.com/products/reflector/)。

        无论如何,如果您想覆盖 DateTime 的格式化方式,请提供您自己的 IFormatProvider。使用 .NET Reflector 了解 DateTimeFormatInfo 是如何实现的,然后自己实现。

        【讨论】:

          【解决方案7】:

          仅仅因为它是一个结构体(或者即使它是一个密封类),这并不意味着它是路的尽头。你可以用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; }
              }
          }
          

          【讨论】:

            【解决方案8】:

            你不需要覆盖 ToString() 方法只需检查模式 here 你不会真的需要其他人:)

            更详细的帖子here

            【讨论】:

              猜你喜欢
              • 2016-02-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-09-27
              • 1970-01-01
              • 1970-01-01
              • 2023-01-20
              相关资源
              最近更新 更多