On partially-constructed objects, additional remarks, not as interesting

Don't worry. Our long national nightmare of CLR week is almost over.

I had originally planned to write an article about partially-constructed objects, but in the time since I queued up the topic (back in November 2005) to the time I got around to writing it up, I found that Joe Duffy had already written it for me!

On partially-constructed objects

Read it.

Okay, here are some follow-up remarks.

One place where people get caught out by partially-constructed objects is when they try to maintain a cache of objects (perhaps with a little bit of Weak­Reference action) and stash the objects into the cache before they are fully constructed:

class SomeClass {
 public SomeClass(...) {

If the Additional­Construction­Work takes an exception, then you end up with a partially-constructed object in your cache. (Mind you, you had one all along, but now it's a persistent condition as opposed to a transient one.)

You might think to fix the problem by reordering the operations:

class SomeClass {
 public SomeClass(...) {
  // add to cache only after construction ran to completion

But that still doesn't work once you have derived classes:

class Derived : SomeClass {
 public Derived(...) : base(...) {
  AdditionalConstruction(); // oops, what if this throws?

The base constructor runs first, it successfully constructs the base object, and then puts it in the cache. And then the derived constructor runs and encounters an exception. You're back in the same boat with a partially-constructed object in the cache.

You want to wait until the object is fully constructed because you add it to your cache.

class SomeClass {
 static public SomeClass Create(...) {
  SomeClass c = new SomeClass(...);
  return c;
 protected static void Register(SomeClass c) { cache.Add(c); }
 protected SomeClass(...) { ... }

class Derived : SomeClass {
 static public Derived Create(...) {
  Derived d = new Derived(...);
  return d;
 public Derived(...) : base(...) { ... }
Comments (14)
  1. Simon says:

    Actually, that is not a problem.

    The base class is fully constructed, so if the derived constructor throws, the base destructor is invoked.

    [I think you've confused C++ with C#. -Raymond]
  2. David says:

    Shouldn't Derived's ctor be protected too?

  3. This blog post was a good reminder to me to re-read http://www.parashift.com/…/exceptions.html

    The amount of gotchas in c++ is frustrating at times.

  4. jader3rd says:

    I've never seen a constructor add itself to a collection. This sounds like another great reason to never do so.

  5. Bret Kuhns says:

    Although your static factory method is a good start, it can be easy for derived types to do incorrectly or not at all. The entire "construct, register, return" pattern is very ad hoc across a hierarchy of types. Unfortunately, because the `Create()` method is static, you can't use polymorphism to implement the virtual template pattern.

    An ideal solution to the problem you presented would be to have a `SomeClassFactory` class that can follow the "construct, register, return" pattern across a hierarchy of types. For example,

    public class SomeClassFactory {

       public Make() {

           SomeClass obj = ConstructObj();


           return obj;


       protected virtual SomeClass ConstructObj() {

           return new SomeClass(…);


       protected virtual SomeClass RegisterObj(SomeClass obj) {




    Now you can subclass `SomeClassFactory` on the protected virtuals to do the appropriate construction and registration steps while enforcing a consistent "construct, register, return" pattern.

  6. Chris B says:

    Along the lines of what jader3rd said, that constructor looks like a good example of an SRP violation to me.

    On another note, it's also interesting to see how features of ORMs like NHibernate and EF interact with auto-properties in C# to encourage accessing partially constructed objects.  For example

    public class Customer


      public Customer(string name)


         this.Name = name; // ruh-roh – invoking virtual member on a partially constructed object


      // must be virtual to allow the dynamically generated

      // ORM proxy to override the member for change tracking

      public virtual string Name { get; set; }


    Of course, this situation can be avoided by implementing the property long-hand, but then you are missing out on the wonderfulness of auto-properties.

  7. Gabe says:

    A search for "our long national nightmare" brings up this [much funnier] link first: http://www.theonion.com/…/bush-our-long-national-nightmare-of-peace-and-pros,464

  8. JM says:

    "Of course, this situation can be avoided by implementing the property long-hand, but then you are missing out on the wonderfulness of auto-properties."

    Um… I think "boo hoo" is the appropriate response here.

    As Franklin might have said, those who would give up essential correctness to purchase small keystroke savings deserve neither correctness nor keystroke savings.

  9. Mark Sowul says:

    @Gabe – that article is scarily prescient, isn't it?  (Note the date).

  10. Chris B says:

    @JM, It may not seem like a big deal, there is more than just a small keystroke savings. If you choose not to use the auto-property, then you need to back the property with an explicitly declared private field. Since the field is private, you cannot lean on the compiler to verify your mappings match your entities (especially those that do not conform to conventions). You trade one form of correctness for another. While I agree that calling virtual methods from a constructor is a more dangerous thing to do than having a mapping fail, it is still an unfortunate and non-obvious confluence of features.

  11. Gabe says:

    Mark Sowul: The Onion is quite amazing in its ability to predict the future: http://www.theonion.com/…/f-everything-were-doing-five-blades,11056

  12. Deduplicator says:

    There's an unfortunate error in the linked article: Virtual calls in base-constructors for C++ get the appropriate implementation (of the level which you just initialize), they are not disallowed. At least he's right about C# always pretending the final object was already constructed.

  13. Someone says:

    @Gabe, Mark Sowul: "The Onion is quite amazing in its ability to predict the future"

    There are a number of such cases. One of my favorites: http://www.theonion.com/…/nation-celebrates-full-week-without-deadly-mass-sh,29293

    If you remember the time when NYPD cops shot at someone and managed to hit 8 or so passer-bys, that article was published the day *before* that. It was *not* published with the "Update: Never Mind".

    There's another forum I frequent where there is a user with the name "The Onion is Prophetic"

  14. Y says:

    The CLR can be loaded dynamically into an existing process. Does it verify that the first 64k are really unmapped?

Comments are closed.