与此问题类似: C# Constructor Design但这个问题略有不同。
我有一个Customer类和一个CustomerManager类。当创建CustomerManager类的实例时,我想加载所有客户。这就是我陷入困境的地方。我可以通过以下几种方式做到这一点:
在执行数据库相关操作的CustomerManager类的每个方法中,检查已加载的本地客户列表,如果没有,请加载列表:
public method FindCustomer(int id)
{
if(_customers == null)
// some code which will load the customers list
}
创建一个加载所有客户的方法。必须在调用执行数据库相关操作的方法之前调用此方法:
在课堂上:
public LoadData()
{
// some code which will load the customers list
}
表格形式:
CustomerManager manager = new CustomerManager();
manager.LoadData();
Customer customer = manager.FindCustomer(int id);
这样做的最佳方式是什么?
编辑:
我觉得我在这里被误解了。也许是因为我不够清楚。在CustomerManager类中,我有几种方法取决于本地列表(_customers)。所以,我的问题是,我应该在哪里填写该列表?
答案 0 :(得分:9)
你所描述的是“延迟加载”。
一个简单的方法是拥有这样的私有财产:
private Lixt<Customer> _customers;
private List<Customer> Customers
{
get
{
if(_customers == null)
_customers = LoadData();
return _customers;
}
}
然后,您在内部引用Customers
。客户将在第一次需要时加载,但不会更早。
这是一种常见的模式,.Net 4.0添加了一个Lazy<T>
类来为您执行此操作。
在这种情况下,您只需将其定义为私有:
private Lazy<List<Customer>> _customers = new Lazy<List<Customer>>(LoadData);
然后,您只需在代码中引用您的客户:
_customers.Value
该课程将使用您的LoadData()
方法初始化该值。
如果您尚未使用.Net 4.0,则Lazy<T>
类非常容易实现。
答案 1 :(得分:5)
使用属性访问客户。检查客户是否已加载。
答案 2 :(得分:2)
嗯,这取决于。您的所有选择都有优点和缺点。
选项1和3的好处是,当(冗长)数据加载操作执行时,用户可以完全控制。选项1或3是否更好取决于创建Manager并在以后加载数据是否有意义。就个人而言,如果这是一个冗长的操作,我更喜欢单独的LoadData
方法,但这可能是一个品味问题。
关于选项2的好处是,如果不需要,将不会加载数据。缺点是(冗长)负载是第一次访问的副作用,这使得您的程序“不那么确定”。
原则上,您提供的所有选项都是精确有效的选择。这实际上取决于您的要求。