我有一个类,当我尝试在另一个类中使用它时,我收到下面的错误.
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
在另一个类中使用该类
class SomeOtherClass
{
private Reminders reminder = new Reminders();
// error happens on this line:
private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
....
Run Code Online (Sandbox Code Playgroud)
错误(CS0236):
A field initializer cannot reference the nonstatic field, method, or property
Run Code Online (Sandbox Code Playgroud)
为什么会发生以及如何解决?
Ode*_*ded 122
这一行:
private dynamic defaultReminder =
reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
Run Code Online (Sandbox Code Playgroud)
您不能使用实例变量来初始化另一个实例变量.为什么?因为编译器可以重新排列这些 - 不能保证reminder之前会被初始化defaultReminder,所以上面的行可能会抛出一个NullReferenceException.
相反,只需使用:
private dynamic defaultReminder = TimeSpan.FromMinutes(15);
Run Code Online (Sandbox Code Playgroud)
或者,在构造函数中设置值:
private dynamic defaultReminder;
public Reminders()
{
defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}
Run Code Online (Sandbox Code Playgroud)
MSDN上有关此编译器错误的更多详细信息 - 编译器错误CS0236.
Dan*_*rth 20
您需要将该代码放入类的构造函数中:
private Reminders reminder = new Reminders();
private dynamic defaultReminder;
public YourClass()
{
defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}
Run Code Online (Sandbox Code Playgroud)
原因是您不能使用一个实例变量来使用字段初始值设定项初始化另一个实例变量,因为字段初始值设定项的执行顺序是未定义的.
小智 6
你可以这样使用
private dynamic defaultReminder => reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
Run Code Online (Sandbox Code Playgroud)
private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];是一个字段初始值设定项并首先执行(在没有初始值设定项的任何字段设置为其默认值之前以及执行调用的实例构造函数之前)。没有初始化器的实例字段将只有在所有实例字段初始化器完成后才具有合法(默认)值。由于初始化顺序,实例构造器最后执行,这就是为什么在执行初始化器时还没有创建实例的原因。因此,在完全构造类实例之前,编译器不允许引用任何实例属性(或字段)。这是因为对实例变量的任何访问,如reminder隐式引用实例 ( this) 以告诉编译器要使用的实例的具体内存位置。
这也是this不允许在实例字段初始值设定项中使用的原因。
实例字段的变量初始值设定项不能引用正在创建的实例。因此,在变量初始值设定项中引用 this 是编译时错误,因为变量初始值设定项通过simple_name引用任何实例成员是编译时错误 。
在执行实例字段初始值设定项之前保证被初始化的唯一类型成员是类(静态)字段初始值设定项和类(静态)构造函数和类方法。由于静态成员是独立于实例的,它们可以随时被引用:
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)];
}
Run Code Online (Sandbox Code Playgroud)
这就是为什么实例字段初始值设定项只能引用类成员(静态成员)的原因。此编译器初始化规则将确保确定性类型实例化。
有关更多详细信息,我推荐此文档:Microsoft Docs:类声明。
这意味着引用另一个实例成员以初始化其值的实例字段必须从实例构造函数初始化,或者必须声明被引用的成员static。
| 归档时间: |
|
| 查看次数: |
156104 次 |
| 最近记录: |