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 removedAnonymous
June 26, 2010
This morning I was refactoring some code and I decided to create a partial class with an overloaded constructorAnonymous
June 26, 2010
This morning I was refactoring some code and I decided to create a partial class with an overloaded constructor