代码之家  ›  专栏  ›  技术社区  ›  xofz

与静态方法相比,不可变对象有哪些优点?

  •  0
  • xofz  · 技术社区  · 16 年前
    interface IDependency
    {
        string Baz { get; set; }
    }
    
    class Foo
    {
        IDependency dependency;
    
        public Foo(IDependency dependency)
        {
            this.dependency = dependency;
        }
    
        public void FubarBaz()
        {
            dependency.Baz = "fubar";
        }
    }
    

    我还可以通过以下方式实现这一点:

    class FooStatic
    {
        public static void FubarBaz(IDependency dependency)
        {
            dependency.Baz = "fubar";
        }
    }
    

    什么时候应该选择不可变对象而不是静态方法?是否存在相反的情况?

    而且,在我看来,不可变对象不应该有void方法。你怎么认为?

    2 回复  |  直到 16 年前
        1
  •  3
  •   Jon Skeet    16 年前

    不可变对象当然会有无效方法——除了改变对象的状态之外,还有其他类型的副作用。考虑:

    public void WriteTo(Stream stream)
    

    至于您的“不可变对象与静态方法”问题——如果您的方法实际上需要几个方面的状态,该怎么办 Foo ? 仅仅因为状态没有改变并不意味着将状态封装在一起是没有意义的。假设它有5个依赖项,而不是一个依赖项-您想写很多采用5个参数的静态方法吗?当您获得第六个依赖项(甚至只是另一个状态)时,您真的想将第六个参数添加到所有方法中,还是只添加到构造函数中?

        2
  •  0
  •   P.Brian.Mackey    11 年前

    FubarBaz()使成员发生变异 Foo.dependency 因此 Foo readonly . 依赖关系的连接可以而且应该在构造函数中完成(如果您正在执行IoC,大多数框架都需要这样做)。一个不变的设计可能会以这样的方式结束:

    class Foo
    {
        private readonly IDependency dependency;
    
        public Foo(IDependency dependency)
        {
            this.dependency = dependency;
            dependency.Baz = "fubar";
        }
    }
    

    使用静态类的决定应该基于您希望调用的外观,或者您是否绝对需要使用静态类,例如创建扩展方法时的情况。在IME中,在实现调用之前编写调用是在连接实现之前决定设计的好方法。静态与非静态基本上是一样的,只是静态不能“新建”(由您构建)。静态不是一成不变的,特别是因为您没有构造它们。你只需要处理一个实例。

    我认为没有理由在不可变类设计中避免方法上的void返回类型。