【问题标题】:Why is this collection initializer trying to be static?为什么这个集合初始化器试图是静态的?
【发布时间】:2011-06-03 07:39:30
【问题描述】:

我正在尝试创建一个非常简单的实体列表,用于我正在编写的一些单元测试,但编译器抱怨我无法从静态上下文访问实例变量。据我所知,只有实例变量。

using System;
using System.Collections.Generic;
using EMP.Domain.Entities;
using NUnit.Framework;

namespace EMP.Domain.Tests.Repositories
{
    [TestFixture]
    public class AuditTrailRepositoryTests
    {
        private Guid orgId1 = Guid.NewGuid();

        private IList<AuditTrail> fakeAuditData = new List<AuditTrail>
                                                      {
                                                          new AuditTrail
                                                              {
                                                                  ChangeDate = new DateTime(2011, 1, 1),
                                                                  EntityName = "Test",
                                                                  OrganisationId = orgId1,
                                                                  Username = "admin"
                                                              }
                                                      };
    }
}

这就是此时类中的所有代码。编译器抱怨

错误 1 ​​字段初始化程序无法引用非静态字段、方法或属性“EMP.Domain.Tests.Repositories.AuditTrailRepositoryTests.orgId1”

是什么导致fakeAuditData 认为它在静态上下文中运行?我什至添加了一个实例方法,并且能够访问集合和 Guid。那么初始化时集合是静态的吗?这是否意味着它只初始化一次?

【问题讨论】:

    标签: .net collections c#-4.0


    【解决方案1】:

    这个问题与集合初始化器本身并没有真正的关系;这是因为在提供的示例中,集合初始化器是 instance 字段初始化器的一部分。这些不允许引用任何实例成员。来自语言规范:

    10.5.5.2 实例字段初始化

    类的实例字段变量初始值设定项对应于在进入该类的任何一个实例构造函数(第 10.11.1 节)时立即执行的一系列赋值。变量初始化器按照它们在类声明中出现的文本顺序执行。第 10.11 节进一步描述了类实例的创建和初始化过程。

    实例字段的变量初始化器不能引用正在创建的实例。因此,在变量初始化器中引用 this 是编译时错误,因为变量初始化器通过简单名称引用任何实例成员是编译时错误。

    【讨论】:

    • 但他没有引用正在创建的实例的类型成员。
    • OrganisationId = orgId1。那里有一个隐含的this.。如果显式添加它不会有什么不同,它仍然是一个编译时错误,尽管不同。
    • @Ani: 但是如果不被视为简单名称,那么错误是什么?
    • @leppie:抱歉,没看懂问题。字段初始化器正在通过简单名称访问另一个字段,不是吗?如果你明确表示,你会得到一个Keyword 'this' is not available in the current context 错误。
    • @Ani:等一下,我现在明白了,这与从声明的构造函数中引用实例变量相同:) 与初始化程序无关。
    【解决方案2】:

    同理,这也是编译时错误:

    class Foo
    {
      int a = 5;
      int b = a;
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用TestFixtureSetUp 为每个单元测试准备假数据:

      [测试夹具]

      public class AuditTrailRepositoryTests
      {
          private Guid orgId1;
          private IList<AuditTrail> fakeAuditData;
      
          [TestFixtureSetUp] 
          public void Init()
          {
              orgId1 = Guid.NewGuid();
              fakeAuditData = new List<AuditTrail>
              {
                  new AuditTrail
                  {
                      ChangeDate = new DateTime(2011, 1, 1),
                      EntityName = "Test",
                      OrganisationId = orgId1,
                      Username = "admin"
                  }
              };
          }
      }
      

      【讨论】:

      • 我可以,但我对集合初始化器的一般行为更感兴趣,而不是具体如何解决这个问题以进行单元测试。
      • 但这会导致同样的错误(如果我理解正确的话)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-19
      • 2018-04-01
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多