Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Don';不能从许多方法中分配字段_C#_Refactoring_Ndepend - Fatal编程技术网

C# Don';不能从许多方法中分配字段

C# Don';不能从许多方法中分配字段,c#,refactoring,ndepend,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 = ... } }

我班上有这样一个领域:

public class Shape
{
    private Point2D m_location;

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

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

    public void Flip()
    {
       m_location = ...
    }
}
我在《独立》杂志上收到一条警告,上面写着:

不要从许多方法中指定字段

似乎我可以通过在我的类中创建另一个方法轻松解决此问题,如:

private void SetLocation(Point2D point)
{
    m_location = location;
}
并在设置
m_位置的所有方法中调用此函数。现在,
m_位置
仅以一种方法分配

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

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

不,正如你所怀疑的,这是一种代码气味。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.
是的,有时您需要可变引用。在这些情况下;记录它们并解释为什么它们必须是可变的。然后,您可以根据具体情况来防止它显示警告。如果你有代码气味,警告人们。不要试图隐藏它

编辑后的示例完全不同,但一般原则仍然适用。如果您只有几个内部字段,所有方法调用中的更改仍然可以返回不可变的引用,例如:

public Shape Move()
{
    return new Shape(m_location ...);
}
如果您有许多内部字段没有全部更改,或者您需要执行诸如共享私有字段之类的操作,那么您不可能轻松拥有不可变引用,但您仍然可以通过使用访问器来避免警告:

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

然后在内部方法中专门使用
Shape.Location

您可以为此字段
public SomeObject SomeObject{get;private set;}
,,但是,是的,拥有另一个私有setter方法也是有效的,因为它使变量完全私有。这是一个类级字段吗?我不知道你的完整代码,所以我不能说是否有“代码气味”,但老实说,我不会仅仅因为工具给你一个警告就创建一个额外的方法,如果必须从这些方法中分配字段,那么就这样做。@CamiloTerevinto是的,它是这个类的组成部分之一。@R1PFake我也不会这样做,我只是好奇这些东西是如何重构的。谢谢你的回答。我改变了问题中的例子,以便更好地表达我的想法。正如您所看到的,在某些情况下,每次使用Move()或Rotate()命令时返回一个新实例并不总是一个好主意。这是一个很好的建议,在可能的情况下支持不可变类,我在过去就这个主题写了一篇完整的文章