不要从许多方法中分配字段

时间:2018-03-18 18:12:07

标签: c# refactoring ndepend

我班上有这样的字段:

public class Shape
{
    private Point2D m_location;

    public void Move()
    {
       m_location = ...
    }

    public void Rotate()
    {
       m_location = ...
    }

    public void Flip()
    {
       m_location = ...
    }
}

我在 NDepend 中收到警告:

  

不要从许多方法中分配字段

https://www.ndepend.com/default-rules/Q_Don't_assign_a_field_from_many_methods.html

我似乎可以通过在我的课程中创建另一种方法来轻松解决这个问题:

private void SetLocation(Point2D point)
{
    m_location = location;
}

并在设置m_location的所有方法中调用它。现在m_location仅在一种方法中分配!

这是解决此问题的有效方法吗?我只是通过在这些方法中调用SetLocation()方法来隐藏之前检测到的代码气味NDepend吗?

1 个答案:

答案 0 :(得分:2)

  

这是解决此问题的有效方法吗?

没有。如你所料,这是一种代码味道。 NDepend抱怨的是可变引用;你有代码在哪里:

var s = new SomeObject(someInitialization);
var r = s.SomeResult();
// you now have no idea what s contains or if it is even usable any more.

解决这个问题的方法是使SomeObject不可变并返回新引用而不是更改内部:

public SomeObject Something()
{
    return new SomeObject(SomethingDifferentDependingOn(this.something));
}

现在代替你的第一个例子:

var s = new SomeObject(someInitialization);
var r = s.Something().Result;
// s is guaranteed to be unchanged.

是的,有时您会需要可变引用。在那些情况下;记录它们并解释为什么它们必须是可变的。然后,您可以根据具体情况override NDepend rules来防止它显示警告。如果你有代码味,请警告人们。不要试图隐藏它。

编辑后的示例完全不同,但一般原则仍然有效。如果您只有几个内部字段在方法调用中都发生了变化,您仍然可以返回不可变引用,例如:

public Shape Move()
{
    return new Shape(m_location ...);
}

如果您有许多内部字段不会全部更改,或者您需要执行类似共享私有字段的操作,则您无法轻松获得不可变引用,但您仍然可以通过使用访问器来避免警告:

public Location
{
    get { return m_location; }
    private set { m_location = value; }
}

然后在您的内部方法中使用Shape.Location