将对象作为构造函数参数传递的最佳实践是什么?传递可变对象可能会导致意外结果。
一个简单的例子。我们期望200,但调用TestMethod()的结果为10000:
public class Test
{
public int TestMethod()
{
var variable1 = new SomeMeasurements
{
Width = 10,
Height = 20
};
var obj1 = new MyRectangle(variable1);
// <... more code...>
variable1.Height = 1000; // a local variable was reused here, and it's field was changed
// <... more code...>
return obj1.GetArea();
}
}
public class SomeMeasurements
{
public int Width { get; set; }
public int Height { get; set; }
}
public class MyRectangle
{
SomeMeasurements _arg;
public MyRectangle(SomeMeasurements arg)
{
_arg = arg;
}
public int GetArea()
{
return _arg.Width * _arg.Height;
}
}
在这种情况下,错误是显而易见的,但是对于更复杂的类,调试可能很乏味。如何解决此问题的几件事已经浮现在我的脑海:
选项1.修复TestMethod()-variable1
创建后不得更改MyRectangle
。
选项2.修复类SomeMeasurements
-将其转换为结构:
public struct SomeMeasurements
{
public int Width { get; set; }
public int Height { get; set; }
}
选项3.修复类SomeMeasurements
-使其不可变:
public class SomeMeasurements
{
public SomeMeasurements(int width, int height)
{
Width = width;
Height = height;
}
public int Width { get; }
public int Height { get; }
}
选项4.修复类MyRectangle
主体-不能使用可变对象:
public class MyRectangle
{
int _height;
int _width;
public MyRectangle(SomeMeasurements arg)
{
_height = arg.Height;
_width = arg.Width;
}
public int GetArea()
{
return _width * _height;
}
}
选项5.制作SomeMeasurements
ICloneable
和使用它Clone()
的MyRectangle
构造函数。
这些选项中的任何一个都有其缺陷-可能很难避免重用variable1,MyRectangle
将其转换为struct可能更复杂,MyRectangle
可以在外部使用,并且可能根本不更改它,等等。修复最正确的方法是什么这个?
这取决于类之间的关系以及它们的设计用途。
如果考虑StreamReader
从Stream
实例构造的类,那么Stream
在读者以给定的方式处理其可变性的同时,它应该继续是具有自己职责的“它自己的”可变类。这两个对象之间存在持续的关系,如果有人对Stream
这里做某事,则希望它会影响读者。
在那种情况下,我们显然只是持有对Stream
传递给构造函数的引用。
在其他情况下,传递的对象表示正在创建的对象的初始状态。两者之间没有持久的关系。
在这里,最好复制传递的对象或其字段。(谈到微光学,复制字段会使初始构造稍微慢一些,而使它们的使用也快一点)。
您要处理的情况是设计中的一部分,因为您可以决定使类以任何一种方式工作。显然有些情况下必须是另一种情况(在该StreamReader
示例中,永远不坚持Stream
所处理的情况是没有意义的),但是通常可以选择。支持最小惊喜原则,如果您仍然无法下定决心,则喜欢复制方法,因为对象之间的依赖关系现在变得更简单,因此对象之间没有持续的关系。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句