C# DateTimeFormatInfo.InvariantInfo与CultureInfo.InvariantCulture

C# DateTimeFormatInfo.InvariantInfo与CultureInfo.InvariantCulture,c#,.net,optimization,datetime,C#,.net,Optimization,Datetime,我试图解析DateTime,从客户端输入中接受精确的格式 哪一个更好 bool success = DateTime.TryParseExact(value, "dd-MMM-yyyy", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dateTime); 或 当然,这段代码在一个通用的静态方法中,只要需要解析日期,就会调用该方法。它们将给出相同的结果。 而且在表现上也不太可能有任何不同 因此,请使用您认为最具可读性

我试图解析DateTime,从客户端输入中接受精确的格式

哪一个更好

bool success = DateTime.TryParseExact(value, "dd-MMM-yyyy",
   DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dateTime);


当然,这段代码在一个通用的静态方法中,只要需要解析日期,就会调用该方法。

它们将给出相同的结果。
而且在表现上也不太可能有任何不同


因此,请使用您认为最具可读性的内容。我的选择是
DateTimeFormatInfo.InvariantInfo
,因为这稍微更切题了一点。

如果您查看
DateTime.TryParseExact
的签名,它会将A作为第三个参数。
DateTimeFormatInfo.InvariantInfo
CultureInfo.InvariantCulture
都实现了这个接口,因此在这两种情况下,实际上都在
DateTime
上调用相同的方法

在内部,如果您使用
CultureInfo.InvariantCulture
,则会调用其属性以获取
DateTimeFormatInfo
实例。如果使用的是
DateTimeFormatInfo.InvariantInfo
,则会直接使用。
DateTimeFormatInfo
调用将稍快一些,因为它必须执行较少的指令,但这将是非常微小的,以至于(几乎)在所有情况下都没有区别


这两种方法的主要区别在于语法。使用你认为最清晰的任何一个。

对于像我这样从谷歌来到这里的人,我发现Matt Weber的以下帖子对于理解实现细节非常有用:

如果链接在某个点中断,请允许我在此引用文章的大部分内容:

DateTimeFormatInfo.CurrentInfo

这将直接返回另一个DateTimeFormatInfo实例,该实例为 设置为当前区域性。为此,它执行以下操作:

  • 从当前线程的CurrentCulture属性(thread.CurrentThread.CurrentCulture)获取CultureInfo。请注意,当您 访问当前线程的CurrentCulture属性时,您需要 基本上访问CultureInfo.CurrentCulture属性(其中 只返回Thread.CurrentThread.CurrentCulture)
  • 如果线程的当前区域性实例本身是基本CultureInfo类型,而不是 派生词。CultureInfo对象的DateTimeFormat属性 在这里不起作用;相反,我们直接阅读的是 从CultureInfo对象的dateTimeInfo私有字段
  • 如果线程的当前区域性实例的日期时间信息字段分配了null,则CultureInfo的GetFormat方法 调用,它返回一个DateTimeFormatInfo实例,然后 返回
  • 如果当前线程的区域性实例实际上是从CultureInfo派生的对象类型,那么它将始终调用 CultureInfo.GetFormat,并且从不从 直接输入CultureInfo.dateTimeInfo字段
  • 所以,如果你曾经处理过从CultureInfo和 设置线程的当前区域性以使用它们,请注意 可以通过重写来修改DateTimeFormatInfo返回的方式 CultureInfo的GetFormat方法

    DateTimeFormatInfo.InvariantInfo

    这将返回另一个设置为的DateTimeFormatInfo实例 文化上不敏感的文化。为此,它执行以下操作:

  • 如果当前应用程序域已经创建了文化不敏感的DateTimeFormatInfo实例,则返回该实例
  • 否则,将使用DateTimeFormatInfo的公共默认构造函数创建一个新实例
  • 新DateTimeFormatInfo实例公开的日历设置为只读
  • 新的DateTimeFormatInfo实例本身设置为只读,然后返回
  • 因此,与DateTimeFormatInfo.CurrentInfo不同,InvariantInfo属性 每个应用程序域而不是每个线程初始化一次。不是很好 这是一个很大的惊喜,但如果你在 做任何冒险和(很可能)不负责任的事情

    CultureInfo.CurrentCulture.DateTimeFormat

    这将返回一个DateTimeFormatInfo对象集以使用当前 文化这是通过以下方式实现的:

  • 因为我们正在访问CultureInfo.CurrentCulture,所以当前线程的CurrentCulture被用作区域性 (Thread.CurrentThread.CurrentCulture)
  • 如果当前线程的区域性实例已初始化DateTimeFormatInfo实例,则将返回该实例(即如果 dateTimeInfo不为null,则返回该值)
  • 否则,将通过直接初始化新的DateTimeFormatInfo实例并传递区域性来创建新的DateTimeFormatInfo对象 将数据发送给构造函数
  • DateTimeFormatInfo实例设置为只读
  • 调用Thread.MemoryBarrier,然后将新初始化的DateTimeFormatInfo实例分配给 dateTimeInfo字段
  • CultureInfo.CurrentCulture.DateTimeFormat与 DateTimeFormat.CurrentInfo?

  • CultureInfo.CurrentCulture.DateTimeFormat属性负责实际初始化DateTimeFormatInfo实例 得到回报;调用DateTimeFormat.CurrentInfo会导致 调用区域性的GetFormat方法,该方法本身将返回 它自己的CultureInfo.DateTimeFormat属性。所以不管在哪里 你开始,你似乎在同一个地方结束。从技术上讲,打电话 CultureInfo.CurrentCulture.DateTimeFormat比调用更直接 DateTimeFormat.CurrentInfo,最终将调用它
  • 当人们开始谈论从CultureInfo派生的对象类型时,就会出现差异。假设我们希望我们的习惯 CultureInfo类返回DateTimeFormatInfo实例,该实例为 以不同于常规的方式修改。过度
    bool success = DateTime.TryParseExact(value, "dd-MMM-yyyy", 
        CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);