c# - 为什么数组初始化在静态上下文中?

标签 c#

让我们考虑一下这个类:

class ABClass
{
    object a;
    object b;

    object[] ab = new[] {a, b};
}

这不编译:

A field initializer cannot reference the non-static field, method, or property 'TestConsole.ABClass.a'
A field initializer cannot reference the non-static field, method, or property 'TestConsole.ABClass.b'

但是,R# 建议这样做以成功修复编译:

class ABClass
{
    object a;
    object b;

    object[] ab;

    public ABClass()
    {
        ab = new[] {a, b};
    }
}

为什么数组初始化似乎发生在静态上下文中?

跟进:在 C# 6 中有 auto-properties with initializers特征。它与我的问题有什么关系?

最佳答案

您已经问过:**为什么**数组初始化**似乎发生**在静态上下文中?

与其向您指出语言的规范(它简单而明确地说“你不能那样做,句号”),不如让我们考虑一下原因。

它发生在静态上下文中,否则它会使用半构造的对象实例。字段 a、b 可能已初始化,也可能未初始化。它们可以从构造函数、基本构造函数或派生构造函数访问,从基本/派生方法,这些方法可以通过虚拟/覆盖从这个或基本构造函数等调用。

如果字段的初始值设定项被允许读取/引用其他实例字段和/或调用实例方法,则编译器无法猜测字段初始化的正确顺序。

此外,请注意字段初始化过程在构造函数之前执行。允许字段访问实例字段/ Prop /方法意味着可以在调用构造函数(和基础构造函数)之前调用这些方法,这将导致许多奇怪和违反直觉的效果。

因此,该语言的设计旨在防止它。初始化程序只是设计/强制在静态上下文中执行,因此您不会想依赖半构造的对象实例功能,也不会使代码过于困惑。这样,您就不会不小心忘记了危险。您仍然可以在构造函数中执行所有这些操作,但您始终知道“它是构造函数”,自然您会更加谨慎。当然,您仍然可以通过从 ctor 调用虚方法来搬起石头砸自己的脚,但是好吧,跟踪和调试要容易得多,因为在构造函数的代码中至少行的执行顺序很明显,而对于初始化器来说可能并非如此。

关于c# - 为什么数组初始化在静态上下文中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26632419/

相关文章:

c# - 操作系统必须支持异步方法或者是异步程序级功能

c# - 在 EMGU CV 中手动对焦相机

c# - 使用 IoC 容器时,原始构造函数参数是一个坏主意吗?

c# - 如何模拟返回 Task<IEnumerable<T>> 和 Task<List<T>> 的方法?

c# - ElasticProperty - 索引在 Nest 中不起作用 - ElasticSearch

c# - 为什么要在 NHibernate session 之上使用工作单元模式?

c# - 计算矩阵对角线上的数字总和

c# - 为什么 Console.Readline() 对其允许的文本长度有限制?

c# - 为什么异常过滤器比捕获和重新抛出更可取?

c# - 为什么 ICommand 比调用 VM 的代码更好?