【问题标题】:How do I implement my own static Empty or Zero field properly如何正确实现自己的静态空或零字段
【发布时间】:2009-07-31 15:28:44
【问题描述】:

我有一个班级,这个班级可以是空的。此类仅具有 String 类型的公共属性。当这个类处于空状态时,这意味着所有的属性都有 String.Empty 的值。

1) 使用公共静态字段,可以修改 Class.Empty 的属性。

2) 我看不到公共静态 property getter 每次都应该返回一个新的空对象(将所有字段设置为 Empty 手动)。我认为这是不好的做法。

3) 另一种解决方案是实现您自己的Class.IsNullOrEmpty(Class obj)

4) 非静态公共布尔属性obj.IsEmpty

在使用此类其他类中,该属性永远不会为空。 其他类是从正确初始化它的(另一个类的)方法返回的。

该属性可能为 null 的唯一情况是,如果它是在该方法之外被 new 的,那么无论如何都会导致它处于无效状态。

【问题讨论】:

    标签: c# class-design


    【解决方案1】:

    1 和 2 基本上是冲突的。

    要么您的类型是不可变的,在这种情况下,您可以每次都返回对同一个实例的引用...或者它是可变的,在这种情况下,您必须返回对新对象的引用每次。

    string.Empty 之所以可以,正是因为string 是不可变的。

    你的类型是可变的吗?

    编辑:根据您的评论,听起来属性根本不应该有设置器。相反,应该将值传递给构造函数,并存储在只读字段中。

    此时您的类型是不可变的,因此您可以公开始终返回相同值的公共字段或属性,即

    private static readonly MyType empty = new MyType("", ""); // Or whatever
    public static MyType Empty { get { return empty; } }
    

    public static readonly MyType Empty = new MyType("", "");
    

    您无需担心任何人设置任何属性,因为您没有任何设置器...

    【讨论】:

    • 我一旦设置了属性,它们就永远不会改变。所以答案是否定的,对吧?
    • 这是真的,这就是我最初通过构造函数设置属性的方式。不幸的是,我忘了提到该类型将使用 XmlSerializer 进行序列化。据我所知,这需要所有序列化属性的公共 get/setter。但是,如果我实现 IXmlSerializable(这是一个注定不会改变的小类),我不需要公共设置器。正确的?如果要更改此类,我不仅要更改/添加字段,还要更改 IXmlSerializable 实现中的字符串?
    • 啊。恐怕我远不是 XML 序列化方面的专家,但这听起来可能会奏效......
    • 如果 Empty 的值在实现之间发生了变化,这不是一个重大变化吗?通常不需要序列化空常量。
    • 这里的特殊问题是引用静态 Empty 然后被序列化和反序列化的对象现在引用静态的副本,因此引用比较将失败。这有时会影响那些序列化 DBNull 并通过引用而不是类对其进行测试的人。
    猜你喜欢
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2020-03-30
    • 2011-06-04
    • 2019-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多