【问题标题】:What is the most concise form of an immutable data class in C#?C# 中不可变数据类的最简洁形式是什么?
【发布时间】:2015-09-27 06:16:21
【问题描述】:

我有一个 enum State 和一个 class Neighborhood 将它们用作数据。我是 C# 的新手,所以我不确定这是惯用的还是更简洁(或完全错误)。

public enum State : byte
{
    zero = 0,
    one = 1,
    two = 2
}

public class Neighborhood
{

    private State _left, _center, _right;

    public Neighborhood(State left, State center, State right)
    {
        _left = left;
        _center = center;
        _right = right;
    }

    public State left { get { return _left; } }

    public State center { get { return _center; } }

    public State right { get { return _right; } }
}

是否有更短或更惯用的方法来做到这一点?

【问题讨论】:

  • 我投票决定将此问题作为题外话结束,因为代码没有任何问题。关于代码审查或改进的问题属于 codereview.stackexchange.com
  • 请注意,除非字段标有readonly,否则您的类并不是真正不可变的。
  • 好吧, 代码出了点问题,所有属性都返回了_left...的值... :)
  • 我认为迁移需要版主干预(即标志)。当然,您始终可以手动完成,只需将问题复制/粘贴到其他站点并在此处删除问题即可。有关如何使用 readonly 关键字及其作用的信息,请参阅 readonly (C# Reference)
  • @kdbanman 我不认为这是迁移到 CR 的最佳帖子。当您拥有来自实际项目的真实工作代码并且您希望就代码的任何和所有方面获得反馈时,代码审查最适合您。这个问题实际上只是在问“关于 X 的最佳实践是什么?”,这在 CR 上显然是题外话(请参阅the help center)。

标签: c# oop properties immutability


【解决方案1】:

这可能不是最简洁的编写方式,但使用readonly 支持字段和private set 自动属性之间存在许多差异:

  • private set 暗示类实现可以改变属性的值。
  • readonly 支持字段只能从构造函数初始化;类实现不能改变它的值。
  • readonly 支持字段更好地传达 intent,如果该意图是使某些东西不可变
  • 带有_namingConvention 的支持字段使this 限定符变得多余。
  • 带有readonly 支持字段的get-only 属性本质上是线程安全的;更多信息here
public class Neighborhood
{
    public Neighborhood(State left, State center, State right)
    {
        _left = left;
        _center = center;
        _right = right;
    }

    private readonly State _left;
    public State Left { get { return _left; } }

    private readonly State _center;
    public State Center { get { return _center; } }

    private readonly State _right;
    public State Right { get { return _right; } }
}

【讨论】:

  • 我想我的课毕竟是不正确的(不可变的)。我优先考虑清晰和正确而不是简洁,所以这是优秀
  • 刚刚识别出一些东西 - Neighborhood 也应该是 sealed 吗?还是子类的只读字段也是安全的?
  • 不知道我怎么看,但如果Jon Skeet says subclassing can break immutability,我相信他。不过,经验法则是永远不要封闭课程,除非你有充分的理由这样做。
  • 好的。还有一件事——为什么不将每个数据字段缩短为public readonly State Left;,并在构造函数中执行Left = left; ?不知道这是否清楚..
  • 你确定会编译吗?
【解决方案2】:
public enum State : byte
{
    zero = 0,
    one = 1,
    two = 2
}

public class Neighborhood
{
    public Neighborhood(State left, State center, State right)
    {
        this.Left = left;
        this.Center = center;
        this.Right = right;
    }

    public State Left { get; private set; }

    public State Center { get; private set; }

    public State Right { get; private set; }
}

【讨论】:

    猜你喜欢
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多