【问题标题】:An object reference is required for the non-static field [duplicate]非静态字段需要对象引用[重复]
【发布时间】:2012-01-05 22:08:01
【问题描述】:

我在代码文件的开头使用静态变量,因为我稍后会使用它来验证值:

static string fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(Data["FirstName"] ));

public void FillName()    {
  Pages.SitecoreCMS.Field_Company.Text = fullNameValue;
}

// break.............

public void VerifyingFullName()    {
  Assert.IsTrue(ArtOfTest.Common.CompareUtils.StringCompare(Pages.Contact.FrameContentIFrame.SitecoreTentativeaccountnameText.Text,fullNameValue, ArtOfTest.Common.StringCompareType.Contains));
}

编译失败:非静态字段、方法或属性“ArtOfTest.WebAii.Design.BaseWebAiiTest.Data.get”需要对象引用

我应该如何更改此代码? 我以前使用过非静态变量,但我不能通过其他方法使用它(例如,VerifyingFullName)。

【问题讨论】:

  • 这不是导致错误的代码。
  • 也许我在这里遗漏了一些东西,但是您收到的错误引用了 Data 属性。发布该属性的代码。
  • 公共 BaseWebAiiTest.TestData 数据 { 获取; }
  • @algot:你不能把它变成静态的吗?
  • Convert.ToInt32(Data["FirstName"] ) - 名字到 int?令人困惑。

标签: c#


【解决方案1】:

正如错误所说:您的 Data 属性是非静态的。将其设为静态以在静态上下文中访问它。

但是,由于您的代码 sn-p 仅在非静态上下文中引用 fullNameValue 字段,您可能可以将 fullNameValue 声明为实例变量,您的代码就可以了。

【讨论】:

    【解决方案2】:

    好吧,您可以将您的 fullNameValue 字段修改为以下代码。我认为这将解决您的错误。

    问题似乎是您的 fullNameValue 字段的初始化代码引用了 Data 属性 (Data["FirstName"]),但 Data 是实例属性,而不是静态属性,因此您不能在静态上下文中引用它(即初始化静态字段时)。

        static object _syncLock = new object();
        static string _fullNameValue;
    
        string fullNameValue
        {
            get
            {
                lock (_syncLock)
                {
                    if (_fullNameValue == null)
                    {
                        _fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(Data["FirstName"]));
                    }
                    return _fullNameValue;
                }
            }
        }
    

    您似乎将其用于单元测试目的。在这种情况下,在我看来,这段代码将为 fullNameValue 生成一个值,并将在所有测试用例中重用该值。

    如果这就是你想要的,那么就可以了。但是,我的猜测是,如果您开始对不同的测试使用不同的测试数据,您可能会发现此代码的行为不正确,尽管我不熟悉 ArtOfTest 框架。如果这给您带来麻烦,那么您可能需要重新考虑 _fullNameValue 字段是否应为 static


    或者,如 cmets 中所述,您可以将 fullNameValue 字段设为非静态字段,然后在构造函数中对其进行初始化。下面是代码:

        string fullNameValue;
        string companyValue;
    
        public PricingForm()
        {
            fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(Data["FirstName"]));
            companyValue = // code to initialize company value
        }
    


    还有另一种选择:您可能想尝试将 fullNameValue 字段转换为属性。同样,这可能会产生与上述示例不同的行为。即使输入参数相同,每次调用 GenerateUniqueId 是否都返回不同的值?那么这意味着每次访问此属性时,您都会得到不同的值,因此请考虑这是否是您想要的。
        string fullNameValue
        {
            get { return UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(this.Data["FirstName"])); }
        }
    


    根据 cmets 中的讨论,我的建议是使用如下所示的方法。

    这将执行 _fullNameValue 字段的延迟初始化(这似乎是必要的,因为 BaseWebAiiTest 类的 Data 属性在构造函数执行时未初始化)。我省略了锁定代码,因为它可能不是必需的,并且 OP 对它的冗长表示担忧。

    string _fullNameValue;
    
    string fullNameValue
    {
        get
        {
            if (_fullNameValue == null)
                _fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(this.Data["FirstName"]));
    
            return _fullNameValue;
        }
    }
    

    【讨论】:

    • 也许我不能使用静态变量?公共类 PricingForm : BaseWebAiiTest` { string fullNameValue = UniqueIdGenerator.GenerateUniqueId(Convert.ToInt32(Data["FirstName"])); public void FillFullName() { // 在“Field_FullName”中输入文本 Pages.SitecoreCMS.Field_FullName.Text = this.fullNameValue; } }
    • @algot - 是的,这也可以。行为会略有不同(您的 PricingForm 类的每个实例都有自己唯一的 fullNameValue 值,而不是所有实例都具有相同的值),但这可能是您想要的。
    • 我以这种方式更改代码,但仍然出现错误。 非静态字段需要对象引用
    • @algot - 啊,对不起。您可以尝试在构造函数中将值分配给 fullNameValue。我会用代码更新我的答案。
    • 我将此变量用于一项测试。所以我不需要在不同的测试中重用它。您的代码正在运行,但如果我需要确定多个变量,我该怎么办?每一个都写一遍这样的代码? o_O
    【解决方案3】:

    您还必须将Data 变量设置为static。您将 fullNameValue 声明为 static,这意味着您处于静态上下文中,因此无法使用实例变量,因为 static 与类的任何实例都没有关联。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多