繁体   English   中英

如何强制C#构造函数成为工厂?

[英]How can I force a C# constructor to be a factory?

下面的代码包含两个类

  • SmartForm (简单模型类)
  • SmartForms (包含SmartForm对象集合的多个类)

我希望能够实例化这样的单数和复数类(即我不想工厂方法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;
            }
        }
    }
}

您无法让一个对象“成为”另一个对象。

使用静态方法而不是构造函数(并使构造函数私有/内部/任何形式,以便只有静态方法才能访问它们)。 在构造函数上使用静态方法有很多好处:

  • 您可以根据需要返回null
  • 您可以根据需要返回现有对象
  • 您可以做很多工作, 然后调用一个简单的构造方法来设置字段

缺点是它们不适用于C#集合/对象初始值设定项:(

静态方法的一种替代方法(诚然,它不能很好地与依赖项注入配合使用)是拥有一个单独的工厂并在其上调用实例方法。

它不必是完全相同的对象,它只需要看起来对外部观察者是相同的即可。 如果将所有数据从一个对象复制到另一个对象,它将完成同一件事。

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

你不能。 Microsoft通过定义一个公共的静态Create()方法来做到这一点。 例如,请参阅System.Net命名空间中的WebRequest和HttpWebRequest。 我建议你这样做。

将基类的构造函数设置为内部或私有,因此无法直接实例化。 或更妙的是,使其成为抽象类。 在Create()实现中使用隐藏的构造函数。

您可以为构造器使用internalprotected修饰符,而不是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单数构造函数在SmartForms复数中找到正确的SmartFormData实例。

然后,使SmartForm所有属性SmartForm奇异,以从SmartFormData获取它们的值。

但是,最好的方法是拥有私有构造函数并使用工厂方法。

是否有理由必须使用构造函数?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM