Как я могу заставить конструктор C # быть фабрикой?

StackOverflow https://stackoverflow.com/questions/970692

  •  13-09-2019
  •  | 
  •  

Вопрос

Приведенный ниже код состоит из два класса:

  • Интеллектуальная форма (класс простой модели)
  • Интеллектуальные формы (множественный класс , содержащий коллекцию Интеллектуальная форма объекты)

Я хочу иметь возможность создавать экземпляры как единственных, так и множественных классов вот так (т.е.Мне не нужен заводской метод GetSmartForm()):

SmartForms smartForms = new SmartForms("all");
SmartForm smartForm = new SmartForm("id = 34");

Для закрепления логики, доступ к базе данных должен иметь только множественный класс.Единственный класс, когда его попросят создать экземпляр самого себя, просто создаст экземпляр множественного класса, затем выберет один объект из коллекции множественного объекта и станьте этим объектом.

Как мне это сделать? Я попытался присвоить объект this что не работает.

using System.Collections.Generic;

namespace TestFactory234
{
    public class Program
    {
        static void Main(string[] args)
        {
            SmartForms smartForms = new SmartForms("all");
            SmartForm smartForm = new SmartForm("id = 34");
        }
    }

    public class SmartForm
    {
        private string _loadCode;

        public string IdCode { get; set; }
        public string Title { get; set; }

        public SmartForm() {}

        public SmartForm(string loadCode)
        {
            _loadCode = loadCode;
            SmartForms smartForms = new SmartForms(_loadCode);
            //this = smartForms.Collection[0]; //PSEUDO-CODE
        }

    }

    public class SmartForms
    {
        private string _loadCode;

        public List<SmartForm> _collection = new List<SmartForm>();
        public List<SmartForm> Collection
        {
            get
            {
                return _collection;
            }
        }

        public SmartForms(string loadCode)
        {
            _loadCode = loadCode;
            Load();
        }

        //fills internal collection from data source, based on "load code"
        private void Load()
        {
            switch (_loadCode)
            {
                case "all":
                    SmartForm smartFormA = new SmartForm { IdCode = "customerMain", Title = "Customer Main" };
                    SmartForm smartFormB = new SmartForm { IdCode = "customerMain2", Title = "Customer Main2" };
                    SmartForm smartFormC = new SmartForm { IdCode = "customerMain3", Title = "Customer Main3" };
                    _collection.Add(smartFormA);
                    _collection.Add(smartFormB);
                    _collection.Add(smartFormC);
                    break;
                case "id = 34":
                    SmartForm smartForm2 = new SmartForm { IdCode = "customerMain2", Title = "Customer Main2" };
                    _collection.Add(smartForm2);
                    break;
                default:
                    break;
            }
        }
    }
}
Это было полезно?

Решение

Это не обязательно должен быть точно такой же объект, он просто должен казаться одинаковым внешним наблюдателям.Если вы скопируете все данные из одного объекта в другой, это приведет к тому же результату.

public SmartForm(string loadCode)
{
    _loadCode = loadCode;
    SmartForms smartForms = new SmartForms(_loadCode);
    this.IdCode = smartForms[0].IdCode;
    this.Title = smartForms[0].Title;
}

Другие советы

Вы не можете заставить один объект "стать" другим.

Используйте статические методы вместо конструкторов (и сделайте конструкторы закрытыми / внутренними / какими угодно, чтобы только статические методы могли получить к ним доступ).Использование статических методов вместо конструкторов имеет множество преимуществ:

  • Вы можете вернуть null, если это уместно
  • Вы можете вернуть существующий объект, если это необходимо
  • Вы можете проделать много работы и тогда вызовите простой конструктор, который просто устанавливает поля

Недостатком является то, что они не работают с инициализаторами коллекции / объекта C # : (

Альтернативой статическим методам (которые, по общему признанию, плохо работают с внедрением зависимостей) является создание отдельной фабрики и вызов методов экземпляра на ней.

Ты не можешь.Microsoft делает это, определяя вместо этого общедоступный статический метод Create().Смотрите, например, WebRequest и HttpWebRequest в системе.Пространство имен Net.Я предлагаю вам сделать то же самое.

Сделайте конструктор базового класса внутренним или закрытым, чтобы его нельзя было создать напрямую.Или еще лучше, сделайте это абстрактным классом.Используйте скрытые конструкторы в вашей реализации Create().

Вы могли бы использовать internal или protected модификатор для конструктора, вместо public.Такой , что:

public SmartForm() {}
public SmartForm(string loadCode)
{
    _loadCode = loadCode;
    SmartForms smartForms = new SmartForms(_loadCode);
    //this = smartForms.Collection[0]; //PSEUDO-CODE
}

становится:

internal SmartForm() {}
internal SmartForm(string loadCode)
{
    _loadCode = loadCode;
    SmartForms smartForms = new SmartForms(_loadCode);
    //this = smartForms.Collection[0]; //PSEUDO-CODE
}

Вы могли бы создать частный класс под названием SmartFormData, и вложите в него все значения.

Сделайте так, чтобы SmartForms множественный класс поддерживает коллекцию этих объектов и создает SmartForm единственный конструктор найдите нужный экземпляр SmartFormData в SmartForms множественное число.

Затем создайте все свойства в SmartForm единственное число извлекает их значения из SmartFormData

Однако лучший способ сделать это - иметь частный конструктор и использовать фабричный метод.

Есть ли причина, по которой вы должны использовать конструктор?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top