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

时间:2009-06-09 15:13:08

标签: c# constructor instantiation

以下代码包含两个类

  • 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;
            }
        }
    }
}

5 个答案:

答案 0 :(得分:7)

你不能让一个物体“变成”另一个物体。

使用静态方法而不是构造函数(并使构造函数为private / internal / whatever,以便只有静态方法才能访问它们)。使用静态方法而不是构造函数有很多好处:

  • 如果合适,您可以返回null
  • 如果合适,您可以返回现有对象
  • 你可以做很多工作,然后调用一个只设置字段的简单构造函数

缺点是它们不能与C#集合/对象初始化器一起使用:(

静态方法的替代方法(无可否认,依赖注入效果不佳)就是在其上有一个单独的工厂和调用实例方法。

答案 1 :(得分:4)

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

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

答案 2 :(得分:3)

你做不到。 Microsoft通过定义公共静态Create()方法来实现此目的。请参阅System.Net命名空间中的示例WebRequest和HttpWebRequest。我建议你这样做。

使基类的构造函数内部或私有,因此无法直接实例化。或者更好的是,把它变成一个抽象的类。在Create()实现中使用隐藏的构造函数。

答案 3 :(得分:2)

您可以使用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
}

答案 4 :(得分:0)

您可以创建一个名为SmartFormData的私有类,并将所有值放入其中。

使SmartForms复数类维护这些对象的集合,并使SmartForm单数构造函数以SmartForms复数形式找到正确的SmartFormData实例。

然后,让SmartForm奇异的所有属性从SmartFormData

获取其值

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

是否有必要使用构造函数的原因?