问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/26433251/why-cant-a-member-field-have-a-field-initializer-call-a-member-function