下面是我的类,带有静态只读字段:
public class Stats
{
public static readonly int MinPoints = 900;
public static readonly int MaxPoints = 1500;
public int Points { get; }
private Stats()
{
}
public Stats(int points) : this()
{
if (points < Stats.MinPoints || points > Stats.MaxPoints)
{
throw new InvalidOperationException();
}
Points = points;
}
}
编译时,我没有任何错误。但是,当我尝试实例化Stats
对象时,却得到了TypeInitializationException
。当用适当的值替换构造函数中的PlayerStatistics.MaxPoints
时,代码将起作用。
这是单元测试构造函数时出现的错误:
Expected a <System.InvalidOperationException> to be thrown, but found <System.TypeInitializationException>: "
"System.TypeInitializationException with message "The type initializer for 'League.Domain.Player.Stats' threw an exception."
at League.Domain.Player.Stats..ctor(Int32 points) in C:\dev\repos\League\League.Domain\Player\Stats.cs:line 24
at League.Tests.StatsSpecs.<>c__DisplayClass1_0.<Create_stats_with_incorrect_points_should_throw_exception>b__0() in C:\dev\repos\League\League.Tests\StatsSpecs.cs:line 36
at FluentAssertions.Specialized.ActionAssertions.InvokeSubject()
at FluentAssertions.Specialized.DelegateAssertions`1.InvokeSubjectWithInterception()
.
at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
at FluentAssertions.Execution.AssertionScope.FailWith(String message, Object[] args)
at FluentAssertions.Specialized.DelegateAssertions`1.Throw[TException](Exception exception, String because, Object[] becauseArgs)
at FluentAssertions.Specialized.DelegateAssertions`1.Throw[TException](String because, Object[] becauseArgs)
at League.Tests.StatsSpecs.Create_stats_with_incorrect_points_should_throw_exception(Int32 points) in C:\dev\repos\League\League.Tests\StatsSpecs.cs:line 38
这是我的单元测试,用XUnit编写:
[Theory]
[InlineData(899)]
[InlineData(1501)]
public void Create_stats_with_incorrect_points_should_throw_exception(int points)
{
Action action = () => new Stats(points);
action.Should().Throw<InvalidOperationException>();
}
有没有办法在构造函数中仍然使用静态只读字段?
我能够找到解决方案...
我试图简化我的代码,而在类中省略一行:
public class Stats
{
// I didn't put this line of code, so it was working without it
public static readonly Stats New = new Stats(1000);
public static readonly int MinPoints = 900;
public static readonly int MaxPoints = 1500;
public int Points { get; }
private Stats()
{
}
public Stats(int points) : this()
{
if (points < Stats.MinPoints || points > Stats.MaxPoints)
{
throw new InvalidOperationException();
}
Points = points;
}
}
因此,如Dmitry Bychenko所述,在编译时不会分配静态只读字段。因此,如果我将这些行放在我省略的行之前,就像这样:
public static readonly int MinPoints = 900;
public static readonly int MaxPoints = 1500;
public static readonly Stats New = new Stats(1000);
会很好。
感谢他的评论,使用const代替静态的readonly字段使我的代码在任何地方都可以将这两个常量放在我的类中。