Calling virtual method from base class ctor #6136
Replies: 5 comments 18 replies
-
This has been a known aspect of the design of the runtime since 1.0. It's discouraged to call a virtual method from the constructor. What do you suggest that |
Beta Was this translation helpful? Give feedback.
-
Nullable constructor analysis doesn't stop you from accessing any members, virtual or non-virtual, before all the fields are in the expected state (i.e. construction is "complete".) There is an official analyzer to warn users away from accessing virtual members from constructors. https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2214 |
Beta Was this translation helpful? Give feedback.
-
This might be solved if the "validator"-method would ever be added. |
Beta Was this translation helpful? Give feedback.
-
Have you ever thought about a replacement of the |
Beta Was this translation helpful? Give feedback.
-
class Base
{
public Base()
{
this.Foo();
}
protected virtual void Foo() { }
}
class Child : Base
{
string _str = "abc"; // Field initializers are executed before the base constructor
protected override void Foo()
{
Console.Write(this._str.Length);
}
} |
Beta Was this translation helpful? Give feedback.
-
This is a known quirk of C#:
This causes an NRE, despite compiling without any NRT warnings. I'm not sure if it's too late to fix now, but wanted to discuss anyway. Below is a possible solution to the problem.
In my proposal, another constructor is emitted, which is unspeakable, and accepts a new parameter of an enum type: option 1 - execute the "pre" code; option 2 - execute the "post" code; option 3 - execute both "pre" and "post" code.
If this parameter is option 1 or 3, the ctor code from beginning to that new pseudo-label is executed.
Then, if this parameter is option 2 or 3, the ctor code from the new pseudo-label to the end is executed.
The actual ctor just calls the unspeakable ctor with "full" option.
Child
ctor: 1) callsBase
unspeakable ctor with "pre" option, 2) executes its own body, 3) callsBase
unspeakable ctor with "post" option.Basically, the above compiles to:
WRONG SOLUTION
In my proposal, the actual `Base` ctor consists of the code from beginning to that new pseudo-label. (Syntax is up for discussion.) Another method is also output, which consists of the code from the new pseudo-label to the end. `Child` ctor: 1) calls `Base` ctor, 2) executes its own body, 3) calls said `Base` "post-ctor" method. Basically, the above compiles to:
Beta Was this translation helpful? Give feedback.
All reactions