为什么成员字段不能让字段初始化程序调用成员函数? [英] Why can't a member field have a field initializer call a member function?

查看:53
本文介绍了为什么成员字段不能让字段初始化程序调用成员函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在MVC控制器内部,我试图创建一个类似于以下内容的字段:

  Func< MyModel,ViewResult>ModelResult =(模型)=>View("myview.cshtml",模型); 

这会导致编译错误

非静态字段,方法或对象需要对象引用属性'System.Web.Mvc.Controller.View(字符串,对象)'

此代码可以很好地用作方法

  private ViewResult ModelResult(MyModel模型){返回View("myview.cshtml",model);} 

如果该字段由构造函数初始化,它也可以正常工作

  public MyController(){ModelResult =(模型)=>View("myview.cshtml",模型);} 

为什么将字段初始值设定项视为静态上下文?

解决方案

字段初始化程序以构造函数的相反顺序在构造函数之前运行.也就是说,它们从最高派生类型到最低派生类型运行,并且最低派生类型的字段将在调用任何构造函数之前进行初始化.做出了一项设计决定,即不允许在调用基本类型的构造函数之前引用 this ,或者更广泛地说,是不允许引用来自字段初始值设定项的部分构造的实例.

我认为这是一个明智的决定.如果您不太熟悉该语言,则运行字段初始化程序时对象的状态不如构造函数运行时的对象清晰.构造函数声明的流动方式反映了构造函数被调用的实际顺序,因此更容易推断状态.具体来说,:base()调用出现在构造函数主体之前,这意味着基本构造函数在您输入主体时已经运行.您无法在字段声明站点轻松推断对象的状态,并且实际上字段初始化顺序与Java不同,Java可以说是C#引入时最相似的主流语言.

Inside a MVC controller I attempted to create a field similar to:

Func<MyModel, ViewResult> ModelResult=(model) => View("myview.cshtml", model);

This results in the compilation error

An object reference is required for the non-static field, method, or property 'System.Web.Mvc.Controller.View(string, object)'

This code works fine as a method

private ViewResult ModelResult(MyModel model)
{
    return View("myview.cshtml", model);
}

It also works fine if the field is initialized by the constructor

public MyController()
{
    ModelResult=(model) => View("myview.cshtml", model);
}

Why is the field initializer treated as a static context?

解决方案

Field initializers run before constructors, in the reverse order of constructors. That is, they run from the most derived type up to the least derived type, and the least derived type's fields will be initialized before any of the constructors are called. A design decision was made not to allow this to be referenced before the base type's constructor has been called, or perhaps, more generally, not to allow references to a partially constructed instance from a field initializer.

I think it's a sensible decision. If you are not intimately familiar with the language, the state of the object when a field initializer runs is less clear than when a constructor runs. The way in which a constructor declaration flows reflects the actual order in which constructors are called, so it's easier to reason about the state. Specifically, the : base() call appears before the constructor body, implying the base constructor has already run by the time you enter the body. You cannot infer the object's state as easily at a field declaration site, and in fact the field initialization order differs from Java, which was arguably the most similar mainstream language when C# was introduced.

这篇关于为什么成员字段不能让字段初始化程序调用成员函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆