Well, apparently the most-derived object is already alive before *any* user
constructor code starts running. It's effectively the same as two-phase
construction. This lets you call virtual methods virtually from the
constructor I guess, don't let your virtual methods rely on the constructor
previously running:
public abstract class Ugly : IDisposable
{
public static Ugly Singleton;
public Ugly()
{
System.Diagnostics.Trace.WriteLine("in Ugly::.ctor");
Singleton = this;
throw new NotImplementedException();
}
~Ugly()
{
System.Diagnostics.Trace.WriteLine("in Ugly::.dtor");
}
public virtual void Dispose()
{
System.Diagnostics.Trace.WriteLine("in Ugly:

ispose");
}
public static void Main()
{
try
{
Ugly stepsister = new Uglier();
}
catch (Exception) { }
System.Diagnostics.Trace.WriteLine("first " +
Ugly.Singleton.ToString());
try
{
using (Ugly stepsister = new Uglier()) { }
}
catch (Exception) { }
System.Diagnostics.Trace.WriteLine("second " +
Ugly.Singleton.ToString());
}
}
public class Uglier : Ugly, IDisposable
{
public Uglier()
: base()
{
System.Diagnostics.Trace.WriteLine("in Uglier::.ctor");
Singleton = this;
throw new NotImplementedException();
}
~Uglier()
{
System.Diagnostics.Trace.WriteLine("in Uglier::.dtor");
}
public override void Dispose()
{
System.Diagnostics.Trace.WriteLine("in Uglier:

ispose");
}
}
in Ugly::.ctor
A first chance exception of type 'System.NotImplementedException' occurred
in UselessJunkForDissassembly.exe
first UselessJunkForDissassembly.Uglier
in Ugly::.ctor
A first chance exception of type 'System.NotImplementedException' occurred
in UselessJunkForDissassembly.exe
second UselessJunkForDissassembly.Uglier
The thread 0x9bc has exited with code 0 (0x0).
The thread 0xe80 has exited with code 0 (0x0).
in Uglier::.dtor
in Ugly::.dtor
in Uglier::.dtor
in Ugly::.dtor