C# Where to load initial data in an object?
Similar to this question: C# Constructor Design but this question is slight different.
I have a class Customer and a class CustomerManager. When an instance is created of the CustomerManager class I want to load all the customers. And this is where I got stuck. I can do this several ways:
- Load all the customers in the constructor (I don't like this one because it can开发者_Go百科 take a while if I have many customers)
In every method of the CustomerManager class that performs database related actions, check the local list of customers is loaded and if not, load the list:
public method FindCustomer(int id) { if(_customers == null) // some code which will load the customers list }
Create a method which loads all the customers. This method must be called before calling methods which performs database related actions:
In the class:
public LoadData() { // some code which will load the customers list }
In the form:
CustomerManager manager = new CustomerManager(); manager.LoadData(); Customer customer = manager.FindCustomer(int id);
What is the best way to do this?
EDIT:
I have the feeling that I am misunderstood here. Maybe it is because I wasn't clear enough. In the CustomerManager class I have several methods which depends on the local list (_customers). So, my question is, where should I fill that list?
What you are describing is "lazy loading".
A simple approach is to have a private property like this:
private Lixt<Customer> _customers;
private List<Customer> Customers
{
get
{
if(_customers == null)
_customers = LoadData();
return _customers;
}
}
Then, you refer to Customers
internally. The customers will be loaded the first time they are needed but no earlier.
This is such a common pattern that .Net 4.0 added a Lazy<T>
class that does this for you.
I that case, you just define it as a private like this:
private Lazy<List<Customer>> _customers = new Lazy<List<Customer>>(LoadData);
Then, you simply refer to your customers in code:
_customers.Value
The class will initialize the value with your LoadData()
method.
If you are not on .Net 4.0 yet, the Lazy<T>
class is very easy to implement.
Use a property for accessing the customers. Have that check if the customers are loaded.
Well, it depends. All your options have advantages and disadvantages.
The good thing about options 1 and 3 is that the user has full control over when the (lengthy) data loading operation is performed. Whether option 1 or 3 is better depends on whether it makes sense to create the Manager and load the data later or not. Personally, I prefer a separate LoadData
method if it's a lengthy operation, but that might be a matter of taste.
The good thing about option 2 is that the data will not be loaded if it is not needed. The drawback is that the (lengthy) load occurs as a side-affect of the first access, which makes your program "less deterministic".
In principle, all the options you have presented are fine and valid choices. It really depends on your requirements.
精彩评论