Skip to content

A class over a base runs its instance initializers after the base constructor, where C# runs them before #571

Description

@edgarmesquita

What happens

C# runs a class's instance field and property initializers BEFORE the base constructor, and JavaScript cannot touch this before super(), so a twin assigns them after it. Measured on the class and record emission branch (#413):

class Base0 { public Base0() { Log("base-ctor"); } int b = Log("base-init"); }
class Derived : Base0 { int d = Log("derived-init"); public string P { get; } = Log("derived-prop"); }

new Derived() logs derived-init derived-prop base-init base-ctor in .NET and base-init base-ctor derived-prop derived-init in the browser. A base constructor that calls a virtual member reading a derived field sees it unset in the browser and initialized in .NET.

The record twins of that branch evaluate each initializer that runs code into a local before super() and assign it after, which keeps the order of the side effects; a plain class does not yet.

Direction

The same rule for a plain class: evaluate each derived initializer before super(), in declaration order, and assign after it. Conformance cases on both sides for the order of the side effects, and for a base constructor reading a derived field through a virtual member, which no twin can give the initialized value before super() returns, and which should be fenced or documented if it cannot be reached.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions