【问题标题】:C# Can/should a List<> of a class be a static member of the same class?C# 一个类的 List<> 可以/应该是同一个类的静态成员吗​​?
【发布时间】:2015-04-17 08:21:16
【问题描述】:

我的例子:

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 类本身中静态定义)正在按我的预期填充。

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

【问题讨论】:

  • 因为公共领域是个坏主意?因为全局可变状态是个坏主意?虽然在打字方面很好 - 而且它并不完全不常见,例如工厂方法返回缓存实例。
  • 静态列表有一个所有线程都可以访问的固定内存地址。但是,它是可变的,并且可以更改项目。这些更改可能是并发的,这将导致线程安全问题。 List&lt;T&gt; 和类似的集合不是线程安全的,你必须实现全局锁定(这也很尴尬和危险)。
  • 到目前为止,所有的 cmets 和答案都具有教育意义。我相信,我不理解的是我自己缺乏 OOP 知识。我会做更多的研究。我会给你们一个 +1,但我的代表仍然
  • @SlowCoder74:你写的代码很好用(是正确的)。但洞察力表明,包含过多此类代码的项目注定要失败。所以如果你打算写一个小项目没问题,但对于工业项目不建议这样做。

标签: c# list class


【解决方案1】:

实际上,这段代码显示了很多(非常)糟糕的设计。

首先一个更好的不会公开字段。所有其他类/对象现在可以更改对象中该变量的值。也许您没有看到太多问题,但是想象一下,在某个时间点您想要限制变量可以具有的值的范围,或者它取决于另一个字段的值。属性(带有 getter 和 setter)和方法用于屏蔽字段免受外部使用,它们需要保证对象始终处于有效状态。

接下来关于列表,同样不要公开此类列表 - 除非您确信没有问题 -。但此外,使用statics 也被一些研究人员认为是糟糕的设计。该列表维护一个状态,但由于它是静态的,因此这是一个全局状态。全局状态是有问题的,因为它们不允许(简单的)单元测试,并且如果由于某种原因列表不应该是全局的,则可能会出现问题。

如果你真的想为数据创建一些访问点,你也许可以考虑创建一个类来存储这样的列表并在你的程序中传递它。


有一些例外,例如 享元 模式,其中一个确实维护了一个全局状态。这些示例仅用于提高性能。例如:

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

}

【讨论】:

  • 我仍在学习很多复杂的 C#。我理解您所说的保持字段私有,并使用 get/set 属性来管理它们。 (抱歉,我在编辑过程中按了 Enter,它保存了我的评论)。你能解释一下将列表放在不同的类中对代码有什么好处吗?
  • @SlowCoder74:这与 C# 没有太大关系。多年来,程序员已经发现了如何在 OO 编程语言中实现概念的见解。 Gang of FourDesign Patterns 书是一个不错的结果。
【解决方案2】:

有时会使用这种解决方案,例如实现 Singleton 或 Register-Resolve 模式。

但您应该记住,它不太适合多线程环境。通常,静态集合应该是私有的,并且访问方法(包括属性 getter 和 setter)应该是同步的。

此外,静态字段/属性很难进行单元测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-08
    • 2021-10-05
    • 1970-01-01
    • 2015-06-19
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    相关资源
    最近更新 更多