Reputation: 93
My example:
class MyClass
{
public int a = 1;
public static List<MyClass> list = new List<MyClass>();
}
class Program
{
static void Main(string[] args)
{
MyClass.list.Add(new MyClass() { a = 5 });
MyClass.list.Add(new MyClass() { a = 10 });
foreach (MyClass item in MyClass.list) Console.WriteLine(item.a);
Console.ReadKey();
}
This code works, and shows that my list, which is statically defined within the MyClass class itself, is populating as I'd expect.
Is there any reason not to define my list in this manner?
Upvotes: 2
Views: 2707
Reputation: 476534
Actually this code shows a lot of sign of (very) bad desing.
First of all one better doesn't make fields public. All other classes/object can now alter the value of that variable in objects. Perhaps you don't see much problems with that, but imagine that at one point in time you want to restrict the range of values that variable can have, or that it depends on the value of another field. Properties (with getters and setters) and methods are used to shield an field from external usage, they need to guarantee that the object always remains in a valid state.
Next about the list, again don't make such lists public - unless you are confident that there is no problem -. But furthermore using static
s is by some researchers considered to be bad design as well. The list maintains a state, but since it is static, this is a global state. Global states are problematic since they don't allow (easy) unit testing, and can become problematic if for some reason the list should be not that global.
In case you really want to make some access point for data, you can perhaps consider making a class that stores such list and pass it around in your program.
There are a few exceptions, for instance the Flyweight pattern where one indeed maintains a global state. Those examples are merely used to increase performance. For instance:
public class FlyWeightInstance {
private int value; //<- private field
private static Dictionary<int,FlyWeightInstance> dic = new Dictionary<int,FlyWeightInstance>(); //<- private static cache
private int FlyWeightInstance (int value) { // <-- private constructor
this.value = value;
}
public static FlyWeightInstance (int value) {
FlyWeightInstance res;
if(!dic.TryGetValue(value,out res)) {
res = new FlyWeightInstance(value);
dic.Add(value,res);
}
return res;
}
}
Upvotes: 2
Reputation: 8197
Such a solution is used sometime, f.e. to implement the Singleton or Register-Resolve patterns.
But you should keep in mind that it's not well suited for multithread environment. Typically, a static collection should be private, and access methods (including property getter and setter) should be synchronized.
In additional, static fields/properties are difficult to an unit testing.
Upvotes: 4