简体   繁体   English

在构造函数 C# 中使用 static 只读字段

[英]Use a static readonly field in constructor C#

Below is my class with a static readonly field:下面是我的 class 与 static 只读字段:

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;
    }
}

When compiling, I don't have any errors.编译时,我没有任何错误。 But when I try to instanciate a Stats object, I'm getting a TypeInitializationException .但是当我尝试实例化Stats object 时,我得到了TypeInitializationException When replacing PlayerStatistics.MaxPoints in the constructor with its proper value, the code works.当用适当的值替换构造函数中的PlayerStatistics.MaxPoints时,代码可以工作。

Here is the error I get when unit testing the constructor:这是我在对构造函数进行单元测试时遇到的错误:

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

And here is my unit test, written with XUnit:这是我用 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>();
}

Is there a way to still use the static readonly field in the constructor?有没有办法在构造函数中仍然使用 static 只读字段?

I was able to find the solution...我能够找到解决方案...

I tried to simplify my code too much, and omitted to put a line in my class:我试图过多地简化我的代码,并在我的 class 中省略了一行:

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;
    }
}

So as mentioned Dmitry Bychenko, static readonly field are not assign at compile time.因此,正如 Dmitry Bychenko 所述,static 只读字段在编译时未分配。 So if I were to put these lines before the line I ommited, like this:因此,如果我将这些行放在我省略的行之前,如下所示:

public static readonly int MinPoints = 900;
public static readonly int MaxPoints = 1500;

public static readonly Stats New = new Stats(1000);

It would work fine.它会工作得很好。

And thanks to his comment, using const instead of a static readonly field make my code work, at any place I put these these two constants in my class.并且感谢他的评论,使用 const 而不是 static 只读字段使我的代码工作,在任何地方我将这两个常量放在我的 class 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM