不要从许多方法中分配一个字段
Don't assign a field from many methods
我的 class:
中有这样一个字段
public class Shape
{
private Point2D m_location;
public void Move()
{
m_location = ...
}
public void Rotate()
{
m_location = ...
}
public void Flip()
{
m_location = ...
}
}
我在 NDepend 中收到一条警告:
Don't assign a field from many methods
https://www.ndepend.com/default-rules/Q_Don't_assign_a_field_from_many_methods.html
看来我可以通过在 class 中创建另一个方法轻松解决这个问题,例如:
private void SetLocation(Point2D point)
{
m_location = location;
}
并在所有设置 m_location
的方法中调用它。现在 m_location
仅在一种方法中分配!
这是解决这个问题的有效方法吗?我是否只是通过在这些方法中调用 SetLocation() 方法来隐藏之前检测到的代码味道 NDepend?
Is this a valid way to solve this problem?
没有。正如您所怀疑的,这是一种代码味道。 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
不可变和 return 新引用而不是更改内部结构:
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.
是的,有时您需要可变引用。在那些情况下;记录它们并解释为什么它们必须是可变的。然后你可以在 case-by-case 的基础上 override NDepend rules 来防止它显示警告。如果您有代码气味,请警告人们。不要试图隐藏它。
你编辑后的例子有很大的不同,但总的原则仍然成立。如果您只有几个内部字段在方法调用中全部更改,您仍然可以 return 不可变引用,例如:
public Shape Move()
{
return new Shape(m_location ...);
}
如果你有很多不会全部改变的内部字段,或者你需要做一些事情,比如共享私有字段,你就不能轻易地拥有不可变的引用,但你仍然可以通过使用访问器来避免警告:
public Location
{
get { return m_location; }
private set { m_location = value; }
}
然后在您的内部方法中专门使用 Shape.Location
。
我的 class:
中有这样一个字段public class Shape
{
private Point2D m_location;
public void Move()
{
m_location = ...
}
public void Rotate()
{
m_location = ...
}
public void Flip()
{
m_location = ...
}
}
我在 NDepend 中收到一条警告:
Don't assign a field from many methods
https://www.ndepend.com/default-rules/Q_Don't_assign_a_field_from_many_methods.html
看来我可以通过在 class 中创建另一个方法轻松解决这个问题,例如:
private void SetLocation(Point2D point)
{
m_location = location;
}
并在所有设置 m_location
的方法中调用它。现在 m_location
仅在一种方法中分配!
这是解决这个问题的有效方法吗?我是否只是通过在这些方法中调用 SetLocation() 方法来隐藏之前检测到的代码味道 NDepend?
Is this a valid way to solve this problem?
没有。正如您所怀疑的,这是一种代码味道。 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
不可变和 return 新引用而不是更改内部结构:
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.
是的,有时您需要可变引用。在那些情况下;记录它们并解释为什么它们必须是可变的。然后你可以在 case-by-case 的基础上 override NDepend rules 来防止它显示警告。如果您有代码气味,请警告人们。不要试图隐藏它。
你编辑后的例子有很大的不同,但总的原则仍然成立。如果您只有几个内部字段在方法调用中全部更改,您仍然可以 return 不可变引用,例如:
public Shape Move()
{
return new Shape(m_location ...);
}
如果你有很多不会全部改变的内部字段,或者你需要做一些事情,比如共享私有字段,你就不能轻易地拥有不可变的引用,但你仍然可以通过使用访问器来避免警告:
public Location
{
get { return m_location; }
private set { m_location = value; }
}
然后在您的内部方法中专门使用 Shape.Location
。