是否值得缓存一个成员结构?

Is it worth caching a member struct?

我有一个 属性 是这样的:

DateTime MinDate
{
    get { return new DateTime(2005, 3, 25); }
}

我担心的是每次调用 Derived.MinDate 都会构造一个新的 DateTime,所以我希望有一个仅构造一次的基础 _MinDate

private readonly DateTime _MinDate = new DateTime(2005, 3, 25);

DateTime MinDate
{
    get { return _MinDate; }
}

但这有任何影响吗,因为 DateTime 无论如何都是一个结构? 场景一:MinDate构造一个新的DateTime,然后复制给调用者。 场景二:_MinDate复制到MinDate,复制到调用方。这两种情况都同样低效,对吧?

几乎正确;没有理由这样做。

通过缓存结构,您需要复制缓存值的字节。

通过构造它,您需要调用构造函数,它将设置结构的字段。

如果构造函数执行昂贵的工作,缓存可能会有用。

DateTime constructor 做了很多工作,所以如果你多次调用 属性,它可能是值得的。
但是,您应该仅在实际遇到性能问题时才执行此操作。

在内部,DateTime(Int32, Int32, Int32) 构造函数非常便宜:它执行简单的乘法运算将年、月和日转换为内部 64 位 "Tick" 值。

据我所知,CLR 不会缓存确定性结构构造函数实例(但这将是一个很好的优化!)。

但是,如果你每秒调用构造函数数百次,我只会缓存这个值,但如果你真的想要,那么这个可行:

private static readonly DateTime _minDate = new DateTime( 2005, 3, 25 );
protected override DateTime MinDate { get { return _minDate; } }

您关于传递给另一个变量时被复制的概念是正确的,因为 DateTime 是一个结构。

这是实现您所追求目标的一种方法:-

abstract class Base
{
    protected abstract void GetMinDate (ref DateTime minDate);
}

class Derived
{
    private static readonly DateTime _MinDate;
    static Derived()
    {
       _MinDate = new DateTime(2005, 3, 25);
    }
    protected override void GetMinDate (ref DateTime minDate);
    {
        minDate = _MinDate;
    }
}

GetMinDate 将始终return ref 的最小日期,复制或不复制将由调用者决定。

从 C# 6.0 开始,现在有一种更简单的方法可以使用自动实现的 属性 初始化程序来执行此操作:

DateTime MinDate { get; } = new DateTime(y, m, d);

编辑: 这实际上是该功能的预期用途,支持字段由编译器自动生成 readonly;事实上,您可以在构造函数中对它们执行 set 操作。它们被称为 "getter-only auto-properties." 有关详细信息,请参阅 here