如何设置DateTimeFormatInfo.CurrentInfo和NumberFormatInfo.CurrentInfo不变?
How to set DateTimeFormatInfo.CurrentInfo and NumberFormatInfo.CurrentInfo to invariant?
我正在重构一些单元测试,发现一些解析策略依赖于 DateTime.TryParseExact
和 sbyte.TryPase
,它们本身依赖于 NumberFormatInfo.CurrentInfo
和 DateTimeFormatInfo.CurrentInfo
.
为了正确安排我的单元测试,我决定通过以下方式将 NumberFormatInfo
和 DateTimeFormatInfo
的 CurrentInfo
属性 设置为它们不变的风格:
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
然而,出于好奇,我试图检查相应的 InvariantInfo
是否通过单元测试设置,结果证明没有,它们不是。我想知道在这两个 CurrentInfo
中强制执行 InvariantCulture
我在这里缺少什么
[Fact]
public void ShouldReturnInvariantInfo()
{
CultureInfo.CurrentCulture.NumberFormat = NumberFormatInfo.InvariantInfo;
CultureInfo.CurrentCulture.DateTimeFormat = DateTimeFormatInfo.InvariantInfo;
NumberFormatInfo.CurrentInfo.Should().Be(NumberFormatInfo.InvariantInfo);
DateTimeFormatInfo.CurrentInfo.Should().Be(DateTimeFormatInfo.InvariantInfo);
}
了解底层实现:
NumberFormatInfo.InvariantInfo
:
public static NumberFormatInfo CurrentInfo
{
get
{
CultureInfo currentCulture = CultureInfo.CurrentCulture;
if (!currentCulture._isInherited)
{
NumberFormatInfo numInfo = currentCulture.numInfo;
if (numInfo != null)
return numInfo;
}
return (NumberFormatInfo) currentCulture.GetFormat(typeof (NumberFormatInfo));
}
}
DateTimeFormatInfo.CurrentInfo
:
public static DateTimeFormatInfo CurrentInfo
{
get
{
CultureInfo currentCulture = CultureInfo.CurrentCulture;
if (!currentCulture._isInherited)
{
DateTimeFormatInfo dateTimeInfo = currentCulture.dateTimeInfo;
if (dateTimeInfo != null)
return dateTimeInfo;
}
return (DateTimeFormatInfo) currentCulture.GetFormat(typeof (DateTimeFormatInfo));
}
}
如果我对你的理解是正确的,你想要 运行 一些代码(测试)在 Current
文化下,除了 NumberFormat
和 DateTimeFormat
是 Invariant
。如果是你的情况,我建议 Clone
当前文化并修改克隆:
// Current culture clone
CultureInfo testCulture = CultureInfo.CurrentCulture.Clone() as CultureInfo;
// modified: current culture except Number and DateTime which are Invariant
testCulture.NumberFormat = CultureInfo.InvariantCulture.NumberFormat;
testCulture.DateTimeFormat = CultureInfo.InvariantCulture.DateTimeFormat;
// and, finally, set back as current
CultureInfo.CurrentCulture = testCulture;
我们来看看格式
Console.Write(ReferenceEquals(CultureInfo.CurrentCulture.DateTimeFormat,
CultureInfo.InvariantCulture.DateTimeFormat)
? "Equals"
: "Not Equals");
结果:
Equals
编辑: 为了运行编码using
修改后的文化,我们可以实现一个class 为它:
public class TestCulture : IDisposable {
private CultureInfo m_SavedCulture;
private CultureInfo m_TestCulture;
private bool m_IsDisposed;
public TestCulture() {
m_SavedCulture = CultureInfo.CurrentCulture;
m_TestCulture = CultureInfo.CurrentCulture.Clone() as CultureInfo;
m_TestCulture.NumberFormat = CultureInfo.InvariantCulture.NumberFormat;
m_TestCulture.DateTimeFormat = CultureInfo.InvariantCulture.DateTimeFormat;
CultureInfo.CurrentCulture = m_TestCulture;
}
protected vitrual void Dispose(bool disposing) {
if (disposing) {
if (!m_IsDisposed && ReferenceEquals(CultureInfo.CurrentCulture, m_TestCulture)) {
CultureInfo.CurrentCulture = m_SavedCulture;
m_IsDisposed = true;
}
}
}
public void Dispose() => Dispose(true);
}
然后按如下方式使用:
using (new TestCulture()) {
// Tests which should be run under the specific culture
}
我正在重构一些单元测试,发现一些解析策略依赖于 DateTime.TryParseExact
和 sbyte.TryPase
,它们本身依赖于 NumberFormatInfo.CurrentInfo
和 DateTimeFormatInfo.CurrentInfo
.
为了正确安排我的单元测试,我决定通过以下方式将 NumberFormatInfo
和 DateTimeFormatInfo
的 CurrentInfo
属性 设置为它们不变的风格:
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
然而,出于好奇,我试图检查相应的 InvariantInfo
是否通过单元测试设置,结果证明没有,它们不是。我想知道在这两个 CurrentInfo
InvariantCulture
我在这里缺少什么
[Fact]
public void ShouldReturnInvariantInfo()
{
CultureInfo.CurrentCulture.NumberFormat = NumberFormatInfo.InvariantInfo;
CultureInfo.CurrentCulture.DateTimeFormat = DateTimeFormatInfo.InvariantInfo;
NumberFormatInfo.CurrentInfo.Should().Be(NumberFormatInfo.InvariantInfo);
DateTimeFormatInfo.CurrentInfo.Should().Be(DateTimeFormatInfo.InvariantInfo);
}
了解底层实现:
NumberFormatInfo.InvariantInfo
:
public static NumberFormatInfo CurrentInfo
{
get
{
CultureInfo currentCulture = CultureInfo.CurrentCulture;
if (!currentCulture._isInherited)
{
NumberFormatInfo numInfo = currentCulture.numInfo;
if (numInfo != null)
return numInfo;
}
return (NumberFormatInfo) currentCulture.GetFormat(typeof (NumberFormatInfo));
}
}
DateTimeFormatInfo.CurrentInfo
:
public static DateTimeFormatInfo CurrentInfo
{
get
{
CultureInfo currentCulture = CultureInfo.CurrentCulture;
if (!currentCulture._isInherited)
{
DateTimeFormatInfo dateTimeInfo = currentCulture.dateTimeInfo;
if (dateTimeInfo != null)
return dateTimeInfo;
}
return (DateTimeFormatInfo) currentCulture.GetFormat(typeof (DateTimeFormatInfo));
}
}
如果我对你的理解是正确的,你想要 运行 一些代码(测试)在 Current
文化下,除了 NumberFormat
和 DateTimeFormat
是 Invariant
。如果是你的情况,我建议 Clone
当前文化并修改克隆:
// Current culture clone
CultureInfo testCulture = CultureInfo.CurrentCulture.Clone() as CultureInfo;
// modified: current culture except Number and DateTime which are Invariant
testCulture.NumberFormat = CultureInfo.InvariantCulture.NumberFormat;
testCulture.DateTimeFormat = CultureInfo.InvariantCulture.DateTimeFormat;
// and, finally, set back as current
CultureInfo.CurrentCulture = testCulture;
我们来看看格式
Console.Write(ReferenceEquals(CultureInfo.CurrentCulture.DateTimeFormat,
CultureInfo.InvariantCulture.DateTimeFormat)
? "Equals"
: "Not Equals");
结果:
Equals
编辑: 为了运行编码using
修改后的文化,我们可以实现一个class 为它:
public class TestCulture : IDisposable {
private CultureInfo m_SavedCulture;
private CultureInfo m_TestCulture;
private bool m_IsDisposed;
public TestCulture() {
m_SavedCulture = CultureInfo.CurrentCulture;
m_TestCulture = CultureInfo.CurrentCulture.Clone() as CultureInfo;
m_TestCulture.NumberFormat = CultureInfo.InvariantCulture.NumberFormat;
m_TestCulture.DateTimeFormat = CultureInfo.InvariantCulture.DateTimeFormat;
CultureInfo.CurrentCulture = m_TestCulture;
}
protected vitrual void Dispose(bool disposing) {
if (disposing) {
if (!m_IsDisposed && ReferenceEquals(CultureInfo.CurrentCulture, m_TestCulture)) {
CultureInfo.CurrentCulture = m_SavedCulture;
m_IsDisposed = true;
}
}
}
public void Dispose() => Dispose(true);
}
然后按如下方式使用:
using (new TestCulture()) {
// Tests which should be run under the specific culture
}