次の方法で共有


Partial Classes, Default Constructors – watch Out!

Recently I was working on some code where I was using classes generated by a tool.  I wanted to be able to construct one of these generated types from another type so I decided to use a constructor overload to support this.

  // From file SomeClass.cs - generated by the tool
   public partial class SomeClass
  {
       // ...
  }

Of course you shouldn't alter a generated file, if you do, you run the risk that your changes will be lost so I decided to create a partial class to add this new constructor

   // From file SomeClass.cs - created by me
   public partial class SomeClass
  {
       // My new constructor - construct from SomeOtherType
        public SomeClass(SomeOtherType value)
       {
       }
   }   

Things seemed to be working well until one day (as I'm writing tests) I discover that the generated class isn't behaving properly. At first I assumed this was because I did something wrong with the way I configured or was using it but after a long debugging session I discovered something... The generated class had important code in its default constructor that was not executing because of my overloaded constructor.

   // From file SomeClass.cs - generated by the tool
   public partial class SomeClass
  {
       // Default ctor doing some important initialization!
        public SomeClass()
      {
           SomeReallyImportantFunc();
          SomeReallyImportantMember member = new SomeReallyImportantMember();
     }

   }

What to do now? I could call the same functions from my ctor but what if I regenerate the file with different options and this changes the generated ctor? What I really needed to do was to call the default ctor. I know this is old news to many of you but (and yes this is embarassing to admit) I didn't know how to call the default ctor from my partial class. I knew how to call the base ctor (SomeClass : base()) but after a few minutes I figured it out.

   // From file SomeClass.cs - created by me
   public partial class SomeClass
  {
       // My new constructor - construct from SomeOtherType
        // Call the default ctor so important initialization can be done
        public SomeClass(SomeOtherType value)  : this() 
       {
       }
   }   

Lesson Learned

So what is the bottom line to this story? I would say if you are creating a partial class and overload constructors it would be a very good idea to call the default ctor just like it is a very good idea to call the default base ctor from a derived class.

Comments

  • Anonymous
    February 23, 2009
    The comment has been removed

  • Anonymous
    June 26, 2010
    This morning I was refactoring some code and I decided to create a partial class with an overloaded constructor

  • Anonymous
    June 26, 2010
    This morning I was refactoring some code and I decided to create a partial class with an overloaded constructor