Какова наилучшая практика передачи объектов в качестве аргументов конструктора? Передача изменяемых объектов может привести к неожиданным результатам.Использование изменяемых объектов в качестве аргументов конструктора
Простой пример. Мы ожидаем, что 200, но получить 10000 вызов TestMethod():
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. Fix TestMethod() - она не должна изменять variable1
после создания MyRectangle
.
вариант 2. Fix класс SomeMeasurements
- превратить его в структуры:
public struct SomeMeasurements
{
public int Width { get; set; }
public int Height { get; set; }
}
вариант 3. Fix класс SomeMeasurements
- сделать его неизменное:
public class SomeMeasurements
{
public SomeMeasurements(int width, int height)
{
Width = width;
Height = height;
}
public int Width { get; }
public int Height { get; }
}
вариант 4. Fix class 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
и использовать его в MyRectangle
конструктор Clone()
.
Любой из этих вариантов есть это недостатки - это может быть трудно, чтобы избежать повторного Variable1, MyRectangle
может быть более сложным, чтобы превратить его в структуры, MyRectangle
может быть внешним, и вы можете не менять его на всех, и т.д. Что такое самый правильный способ исправить это?
См. Также http://stackoverflow.com/questions/4327108/what-is-the-meaning-of-data-hiding –