我的例子:
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();
}
此代码有效,并显示我的列表在MyClass类本身内静态定义,正如我所期望的那样填充。
有没有理由不以这种方式定义我的列表?
答案 0 :(得分:4)
这种解决方案有时会被使用,例如。实现Singleton或Register-Resolve模式。
但是你应该记住,它不适合多线程环境。通常,静态集合应该是私有的,并且应该同步访问方法(包括属性getter和setter)。
另外,静态字段/属性很难进行单元测试。
答案 1 :(得分:2)
实际上,这段代码显示了许多(非常)糟糕设计的迹象。
首先,一个更好的不会公开字段。所有其他类/对象现在可以更改对象中该变量的值。也许你没有看到很多问题,但想象一下,你想要限制变量可以拥有的值的范围,或者它取决于另一个字段的值。使用属性(使用getter和setter)和方法来屏蔽字段以防止外部使用,它们需要保证对象始终保持有效状态。
接下来关于该列表,再次不公开此类列表 - 除非您确信没有问题 - 。但是进一步使用static
s被一些研究人员认为是糟糕的设计。该列表维护一个状态,但由于它是静态的,因此这是全局状态。全球各州都存在问题,因为它们不允许(简单)进行单元测试,如果出于某种原因,列表不应该是全球性的,那么就会出现问题。
如果您真的想要为数据创建一些访问点,您可以考虑创建一个存储此类列表的类,并将其传递给您的程序。
有一些例外,例如 Flyweight 模式,其中一个确实维持全局状态。这些示例仅用于提高性能。例如:
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;
}
}