C#可以/应该列出<>一个类是同一个类的静态成员?

时间:2015-02-16 18:24:46

标签: c# list class

我的例子:

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类本身内静态定义,正如我所期望的那样填充。

有没有理由不以这种方式定义我的列表?

2 个答案:

答案 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;
    }

}