Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.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# 使用可变对象作为构造函数参数_C#_Design Patterns - Fatal编程技术网

C# 使用可变对象作为构造函数参数

C# 使用可变对象作为构造函数参数,c#,design-patterns,C#,Design Patterns,将对象作为构造函数参数传递的最佳实践是什么?传递可变对象可能导致意外结果 一个简单的例子。我们期望有200个,但是调用TestMethod()会得到10000个: 选项3。修复类某些度量值-使其不可变: public class SomeMeasurements { public SomeMeasurements(int width, int height) { Width = width; Height = height; }

将对象作为构造函数参数传递的最佳实践是什么?传递可变对象可能导致意外结果

一个简单的例子。我们期望有200个,但是调用TestMethod()会得到10000个:

选项3。修复类
某些度量值
-使其不可变:

public class SomeMeasurements
{
    public SomeMeasurements(int width, int height)
    {
        Width = width;
        Height = height;
    }

    public int Width { get; }
    public int Height { get; }
}
选项4.修复类
MyRectangle
body-它不能使用可变对象:

public class MyRectangle
{
    int _height;
    int _width;

    public MyRectangle(SomeMeasurements arg)
    {
        _height = arg.Height;
        _width = arg.Width;
    }

    public int GetArea()
    {
        return _width * _height;
    }
}
选项5。进行
一些测量
可克隆
并在
MyRectangle
构造函数中使用它的
Clone()


这些选项中的任何一个都有它的缺陷-可能很难避免重用variable1,
MyRectangle
将其转换为结构可能更复杂,
MyRectangle
可以是外部的,您可能根本不会更改它,等等。解决这个问题的最正确方法是什么?

通常,您应该传递符合特定接口的服务,或者只在构造函数中传递不可变对象。如果您想保护构造函数不受外部更改的影响,那么构造函数应该获取传递给它的任何可变数据的副本

一旦数据通过构造函数,它就应该被视为新实例状态的一部分,并且不应该在该实例之外进行修改


您的选项3、4似乎最有用。选项2将修复此问题,因为您将数据的副本传递给构造函数。选项1在许多情况下可能不受您的控制。

这取决于类之间的关系以及它们的设计用途

如果您考虑从<代码>流>代码>实例构造的<代码> StreamReader <代码>类,则<>代码>流<代码>将继续是“它自己的”可变类,具有自己的职责集,而读者以给定的方式处理它的可变性。这两个对象之间存在持续的关系,如果一个人对

做了某件事,那么希望它会影响读者

在这种情况下,我们显然只持有对传递给构造函数的
流的引用

在其他情况下,传递一个对象来表示正在创建的对象的初始状态。两者之间没有持续的关系

在这里,最好复制传递的对象或其字段。(对于micro OPT,复制字段会使初始构造稍微慢一点,使用它们也稍微快一点)


你正在处理的情况是你正在设计的一部分,因为你可以决定让一门课以任何一种方式运作。某些情况显然必须是一种情况或另一种情况(在
StreamReader
示例中,永远不要保留您正在处理的
是没有意义的),但通常是有选择的。支持最小惊奇原则,如果您仍然不能决定支持复制方法,即对象之间没有持续的关系,因为您的依赖关系现在更简单了。

我想您需要发布GetArea()的代码来回答我根本没有更改我的矩形,我只是将“class”更改为“struct”在某些测量中,请参见
public class SomeMeasurements
{
    public SomeMeasurements(int width, int height)
    {
        Width = width;
        Height = height;
    }

    public int Width { get; }
    public int Height { get; }
}
public class MyRectangle
{
    int _height;
    int _width;

    public MyRectangle(SomeMeasurements arg)
    {
        _height = arg.Height;
        _width = arg.Width;
    }

    public int GetArea()
    {
        return _width * _height;
    }
}