Возможно, я обойду это назад ... У меня есть класс, который похож на документ и другой класс, который похож на шаблон. Они оба наследуются от одного и того же базового класса, и у меня есть метод для создания нового документа из шаблона (или из другого документа, метода, который он находится в базовом классе). Итак, если я хочу создать новый документ из шаблона, я просто создаю шаблон и вызываю GetNewDoc();Позвоните в заводскую конструкцию, чтобы получить новую версию «this»
Document doc = mytemplate.GetNewDoc();
В классе Document У меня есть пустой конструктор, создавая новый пустой документ, а также другой конструктор, который принимает идентификатор документа, так что я могу загрузить документ из базы данных. Однако мне также нужен конструктор, который принимает идентификатор шаблона. Таким образом, я могу сделать
Document doc = New Document(TemplateID)
Поскольку класс шаблона уже имеет возможность вернуть документ, я хотел бы конструктор, чтобы сделать что-то вроде
Template temp = new Template(TemplateID);
this = temp.GetNewDoc();
Конечно, я не могу сделать это как «это» доступно только для чтения - и в любом случае это кажется странным. У меня такое чувство, что я очень глуп здесь, поэтому не стесняйтесь кричать :)
Дело в том, что объект, о котором идет речь, довольно сложный с несколькими наборами дочерних объектов и постоянством базы данных на нескольких таблицах, поэтому я не хочу чтобы дублировать слишком много кода. Хотя, я думаю, я мог бы просто получить новый документ из шаблона, а затем скопировать поля/свойства, поскольку коллекции должны следовать достаточно легко - это просто похоже на дублирование.
Пример из более сложного кода:
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;
}
}
}
Как часто это действительно выгодно для вызывающего, чтобы иметь * компилятор-принудительный * гарантировать, что `new Fizzle` вернет новый экземпляр` Fizzle ' `, а не переработанный экземпляр` Fizzle` или экземпляр некоторого производного класса или `null`? Я подозреваю, что основная причина, по которой люди используют публичные конструкторы, заключается в том, что если для построения `Fizzle` требуется один параметр типа` string`, более удобно объявлять конструктор `public`, который принимает одну строку, чем для определения` protected`, а также метод public, который его вызывает. – supercat 2012-10-25 20:11:30