The code below consists of two classes:
下面的代码包含两个类:
- SmartForm (simple model class)
- SmartForms (plural class that contains a collection of SmartForm objects)
SmartForm(简单模型类)
SmartForms(包含一组SmartForm对象的复数类)
I want to be able to instantiate both singular and plural classes like this (i.e. I don't want a factory method GetSmartForm()):
我希望能够像这样实例化单数和复数类(即我不想要工厂方法GetSmartForm()):
SmartForms smartForms = new SmartForms("all");
SmartForm smartForm = new SmartForm("id = 34");
To consolidate logic, only the plural class should access the database. The singular class, when asked to instantiate itself, will simply instantiate a plural class, then pick the one object out of the the plural object's collection and become that object.
要合并逻辑,只有复数类才能访问数据库。当被要求实例化时,单数类将简单地实例化一个复数类,然后从复数对象的集合中选择一个对象并成为该对象。
How do I do that? I tried to assign the object to this
which doesn't work.
我怎么做?我试图将对象分配给不起作用的对象。
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 个解决方案
#1
It doesn't have to be exactly the same object, it just has to appear to be the same to external observers. If you copy all the data from one object to another, it will accomplish the same thing.
它不必是完全相同的对象,它只需要看起来与外部观察者相同。如果将所有数据从一个对象复制到另一个对象,它将完成相同的任务。
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
this.IdCode = smartForms[0].IdCode;
this.Title = smartForms[0].Title;
}
#2
You can't get one object to "become" another.
你不能让一个对象“成为”另一个。
Use static methods instead of constructors (and make the constructors private/internal/whatever so that only the static methods can access them). There are numerous benefits to using static methods over constructors:
使用静态方法而不是构造函数(并使构造函数为private / internal / whatever,以便只有静态方法才能访问它们)。使用静态方法比构造函数有许多好处:
- You can return null if appropriate
- You can return an existing object if appropriate
- You can do plenty of work and then call a simple constructor which just sets fields
如果合适,您可以返回null
如果合适,您可以返回现有对象
你可以做很多工作然后调用一个只设置字段的简单构造函数
The downside is they don't work with C# collection/object initializers :(
缺点是它们不能与C#集合/对象初始化器一起使用:(
An alternative to static methods (which don't work well with dependency injection, admittedly) is to have a separate factory and call instance methods on that.
静态方法的替代方法(无论如何不能很好地使用依赖注入)是在其上有一个单独的工厂和调用实例方法。
#3
You cannot. Microsoft does this by defining a public static Create() method instead. See for example WebRequest and HttpWebRequest in the System.Net namespace. I suggest you do the same.
你不能。 Microsoft通过定义公共静态Create()方法来实现此目的。请参阅System.Net命名空间中的示例WebRequest和HttpWebRequest。我建议你这样做。
Make the base class' constructor internal or private, so it cannot be directly instantiated. Or better yet, make it an abstract class. Make use of the hidden constructors in your Create() implementation.
使基类的构造函数内部或私有,因此无法直接实例化。或者更好的是,将它变成一个抽象类。在Create()实现中使用隐藏的构造函数。
#4
You could use an internal
or protected
modifier for the constructor, instead of public
. Such that:
您可以为构造函数使用internal或protected修饰符,而不是public。这样:
public SmartForm() {}
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
becomes:
internal SmartForm() {}
internal SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
#5
You could make a private class called SmartFormData
, and put all of the values into it.
您可以创建一个名为SmartFormData的私有类,并将所有值放入其中。
Make the SmartForms
plural class maintain a collection of those objects, and make the SmartForm
singular constructor find the right SmartFormData instance in SmartForms
plural.
使SmartForms复数类维护这些对象的集合,并使SmartForm单一构造函数在SmartForms复数中找到正确的SmartFormData实例。
Then, make all of the properties in SmartForm
singular fetch their values from SmartFormData
然后,使SmartForm中的所有属性都能从SmartFormData中获取它们的值
However, the best way to do it is to have a private constructor and use a factory method.
但是,最好的方法是使用私有构造函数并使用工厂方法。
Is there a reason that you have to use a constructor?
你有必要使用构造函数吗?
#1
It doesn't have to be exactly the same object, it just has to appear to be the same to external observers. If you copy all the data from one object to another, it will accomplish the same thing.
它不必是完全相同的对象,它只需要看起来与外部观察者相同。如果将所有数据从一个对象复制到另一个对象,它将完成相同的任务。
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
this.IdCode = smartForms[0].IdCode;
this.Title = smartForms[0].Title;
}
#2
You can't get one object to "become" another.
你不能让一个对象“成为”另一个。
Use static methods instead of constructors (and make the constructors private/internal/whatever so that only the static methods can access them). There are numerous benefits to using static methods over constructors:
使用静态方法而不是构造函数(并使构造函数为private / internal / whatever,以便只有静态方法才能访问它们)。使用静态方法比构造函数有许多好处:
- You can return null if appropriate
- You can return an existing object if appropriate
- You can do plenty of work and then call a simple constructor which just sets fields
如果合适,您可以返回null
如果合适,您可以返回现有对象
你可以做很多工作然后调用一个只设置字段的简单构造函数
The downside is they don't work with C# collection/object initializers :(
缺点是它们不能与C#集合/对象初始化器一起使用:(
An alternative to static methods (which don't work well with dependency injection, admittedly) is to have a separate factory and call instance methods on that.
静态方法的替代方法(无论如何不能很好地使用依赖注入)是在其上有一个单独的工厂和调用实例方法。
#3
You cannot. Microsoft does this by defining a public static Create() method instead. See for example WebRequest and HttpWebRequest in the System.Net namespace. I suggest you do the same.
你不能。 Microsoft通过定义公共静态Create()方法来实现此目的。请参阅System.Net命名空间中的示例WebRequest和HttpWebRequest。我建议你这样做。
Make the base class' constructor internal or private, so it cannot be directly instantiated. Or better yet, make it an abstract class. Make use of the hidden constructors in your Create() implementation.
使基类的构造函数内部或私有,因此无法直接实例化。或者更好的是,将它变成一个抽象类。在Create()实现中使用隐藏的构造函数。
#4
You could use an internal
or protected
modifier for the constructor, instead of public
. Such that:
您可以为构造函数使用internal或protected修饰符,而不是public。这样:
public SmartForm() {}
public SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
becomes:
internal SmartForm() {}
internal SmartForm(string loadCode)
{
_loadCode = loadCode;
SmartForms smartForms = new SmartForms(_loadCode);
//this = smartForms.Collection[0]; //PSEUDO-CODE
}
#5
You could make a private class called SmartFormData
, and put all of the values into it.
您可以创建一个名为SmartFormData的私有类,并将所有值放入其中。
Make the SmartForms
plural class maintain a collection of those objects, and make the SmartForm
singular constructor find the right SmartFormData instance in SmartForms
plural.
使SmartForms复数类维护这些对象的集合,并使SmartForm单一构造函数在SmartForms复数中找到正确的SmartFormData实例。
Then, make all of the properties in SmartForm
singular fetch their values from SmartFormData
然后,使SmartForm中的所有属性都能从SmartFormData中获取它们的值
However, the best way to do it is to have a private constructor and use a factory method.
但是,最好的方法是使用私有构造函数并使用工厂方法。
Is there a reason that you have to use a constructor?
你有必要使用构造函数吗?