C# 字段初始值设定项不能引用非静态字段、方法或属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14439231/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:49:02  来源:igfitidea点击:

A field initializer cannot reference the nonstatic field, method, or property

c#

提问by GibboK

I have a class and when I try to use it in another class I receive the error below.

我有一堂课,当我尝试在另一堂课中使用它时,我收到以下错误。

using System;
using System.Collections.Generic;
using System.Linq;

namespace MySite
{
    public class Reminders
    {
        public Dictionary<TimeSpan, string> TimeSpanText { get; set; }

        // We are setting the default values using the Costructor
        public Reminders()
        {
            TimeSpanText.Add(TimeSpan.Zero, "None");
            TimeSpanText.Add(new TimeSpan(0, 0, 5, 0), "5 minutes before");
            TimeSpanText.Add(new TimeSpan(0, 0, 15, 0), "15 minutes before");
            TimeSpanText.Add(new TimeSpan(0, 0, 30, 0), "30 minutes before");
            TimeSpanText.Add(new TimeSpan(0, 1, 0, 0), "1 hour before");
            TimeSpanText.Add(new TimeSpan(0, 2, 0, 0), "2 hours before");
            TimeSpanText.Add(new TimeSpan(1, 0, 0, 0), "1 day before");
            TimeSpanText.Add(new TimeSpan(2, 0, 0, 0), "2 day before");
        }

    }
}

Using the class in another class

在另一个类中使用该类

class SomeOtherClass
{  
    private Reminders reminder = new Reminders();
    // error happens on this line:
    private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; 
    ....

Error (CS0236):

错误 (CS0236):

A field initializer cannot reference the nonstatic field, method, or property

Why does it happen and how to fix it?

为什么会发生以及如何解决?

采纳答案by Oded

This line:

这一行:

private dynamic defaultReminder = 
                          reminder.TimeSpanText[TimeSpan.FromMinutes(15)];

You cannot use an instance variable to initialize anotherinstance variable. Why? Because the compiler can rearrange these - there is no guarantee that reminderwill be initialized before defaultReminder, so the above line mightthrow a NullReferenceException.

您不能使用一个实例变量来初始化另一个实例变量。为什么?因为编译器可以重新排列这些 - 不能保证reminder之前会被初始化defaultReminder,所以上面的行可能会抛出一个NullReferenceException.

Instead, just use:

相反,只需使用:

private dynamic defaultReminder = TimeSpan.FromMinutes(15);

Alternatively, set up the value in the constructor:

或者,在构造函数中设置值:

private dynamic defaultReminder;

public Reminders()
{
    defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; 
}

There are more details about this compiler error on MSDN - Compiler Error CS0236.

MSDN- Compiler Error CS0236上有关于此编译器错误的更多详细信息。

回答by Daniel Hilgarth

You need to put that code into the constructor of your class:

您需要将该代码放入类的构造函数中:

private Reminders reminder = new Reminders();
private dynamic defaultReminder;

public YourClass()
{
    defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}

The reason is that you can't use one instance variable to initialize another one using a field initializer.

原因是您不能使用一个实例变量来初始化另一个使用字段初始值设定项的变量。

回答by jin wang

you can use like this

你可以这样使用

private dynamic defaultReminder => reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; 

回答by BionicCode

private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];is a field initializer and executes first (before any field without an initializer is set to its default value and before the invoked instance constructor is executed). Instance fields that have no initializer will only have a legal (default) value after all instance field initializers are completed. Due to the initialization order, instance constructors are executed last, which is why the instance is not created yet the moment the initializers are executed. Therefore the compiler cannot allow any instance property (or field) to be referenced before the class instance is fully constructed. This is because any access to an instance variable like reminderimplicitly references the instance (this) to tell the compiler the concrete memory location of the instance to use.

private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];是一个字段初始值设定项并首先执行(在没有初始值设定项的任何字段设置为其默认值之前以及执行调用的实例构造函数之前)。没有初始化器的实例字段将只有在所有实例字段初始化器完成后才具有合法(默认)值。由于初始化顺序,实例构造器最后执行,这就是为什么在执行初始化器时还没有创建实例的原因。因此,在完全构造类实例之前,编译器不允许引用任何实例属性(或字段)。这是因为对实例变量的任何访问,如reminder隐式引用实例 ( this) 以告诉编译器要使用的实例的具体内存位置。

This is also the reason why thisis not allowed in an instance field initializer.

这也是this不允许在实例字段初始值设定项中使用的原因。

A variable initializer for an instance field cannot reference the instance being created. Thus, it is a compile-time error to reference this in a variable initializer, as it is a compile-time error for a variable initializer to reference any instance member through a simple_name.

实例字段的变量初始值设定项不能引用正在创建的实例。因此,在变量初始值设定项中引用 this 是编译时错误,因为变量初始值设定项通过simple_name引用任何实例成员是编译时错误 。

The only type members that are guaranteed to be initialized beforeinstance field initializers are executed are class (static) field initializers and class (static) constructors and class methods. Since static members are instance independent, they can be referenced at any time:

在执行实例字段初始值设定项之前保证被初始化的唯一类型成员是类(静态)字段初始值设定项和类(静态)构造函数和类方法。由于静态成员是独立于实例的,它们可以随时被引用:

class SomeOtherClass
{
  private static Reminders reminder = new Reminders();

  // This operation is allowed,
  // since the compiler can guarantee that the referenced class member is already initialized
  // when this instance field initializer executes
  private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}

That's why instance field initializers are only allowed to reference a class member (static member). This compiler initialization rules will ensure a deterministic type instantiation.

这就是为什么实例字段初始值设定项只能引用类成员(静态成员)的原因。此编译器初始化规则将确保确定性类型实例化。

For more details I recommend this document: Microsoft Docs: Class declarations.

有关更多详细信息,我推荐此文档:Microsoft Docs:类声明

This means that an instance field that references another instance member to initialize its value, must be initialized from the instance constructor or the referenced member must be declared static.

这意味着引用另一个实例成员以初始化其值的实例字段必须从实例构造函数初始化,或者必须声明被引用的成员static