I may be going about this backwards… I have a class which is like a document and another class which is like a template. They both inherit from the same base class and I have a method to create a new document from a template (or from another document, the method it is in the base class). So, if I want to create a new document from a template, I just instantiate the template and call GetNewDoc() on it;
Document doc = mytemplate.GetNewDoc();
In the Document class I have a blank constructor creating a new, blank document as well as another constructor that takes a document ID so I can load the document from the database. However, I would also like a constructor that takes a Template ID. This way I can do
Document doc = New Document(TemplateID)
Because the template class already has the ability to return a document, I’d like the constructor to do something like
Template temp = new Template(TemplateID); this = temp.GetNewDoc();
Of course, I can’t do this as ‘this’ is read-only – and it feels odd anyway. I have a feeling I am being very stupid here so feel free to shout 🙂
The thing is that the object in question is pretty complex with several collections of child objects and database persistence over multiple tables so i don’t want to duplicate too much code. Though, I guess I could just get the new document from the template and then copy the fields/properties across as the collections should follow easily enough – it just seems like duplication.
A more elaborate code example:
using System; using System.Collections.Generic; using System.Text; namespace Test { class Program { static void Main(string[] args) { // This just creates the object and assigns a value Instance inst = new Instance(); inst.name = 'Manually created'; Console.WriteLine('Direct: {0}', inst.name); //This creates a new instance directly from a template MyTemplate def = new MyTemplate(); Instance inst2 = def.GetInstance(100); Console.WriteLine('Direct from template: {0}', inst2.name); Instance inst3 = new Instance(101); Console.WriteLine('Constructor called the template: {0}', inst3.name); Console.ReadKey(); } } public class Instance { public string name; public Instance(int TemplateID) { MyTemplate def = new MyTemplate(); //If I uncomment this line the build will fail //this = def.GetInstance(TemplateID); } public Instance() { } } class MyTemplate { public Instance GetInstance(int TemplateID) { Instance inst = new Instance(); //Find the template in the DB and get some values inst.name = String.Format('From template: {0}', TemplateID.ToString()); return inst; } } }
If you want to be able to do anything other than create a new object just from the code in the constructor, don’t use a constructor in the first place.
Do you really need an Instance constructor taking an int? Why not turn it into a static factory method:
Static methods have various advantages over constructors – although some disadvantages too. (There’s a separate SO question on that – worth a look.)