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

加密器

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

一个简单的例子。我们期望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可以在外部使用,并且可能根本不更改它,等等。修复最正确的方法是什么这个?

乔恩·汉纳

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

如果考虑StreamReaderStream实例构造,那么Stream在读者以给定的方式处理其可变性的同时,它应该继续是具有自己职责的“它自己的”可变类。这两个对象之间存在持续的关系,如果有人对Stream这里做某事,则希望它会影响读者。

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

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

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

您要处理的情况是设计中的一部分,因为您可以决定使类以任何一种方式工作。显然有些情况下必须是另一种情况(在该StreamReader示例中,永远不坚持Stream所处理的情况没有意义的),但是通常可以选择。支持最小惊喜原则,如果您仍然无法下定决心,则喜欢复制方法,因为对象之间的依赖关系现在变得更简单,因此对象之间没有持续的关系。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用Rcpp公开以指向对象的指针作为参数的构造函数

如何使用对象类型作为方法/构造函数的参数?

对象的构造函数作为函数参数

将对象作为构造函数的参数传递

数组作为对象构造函数中的参数

以模板化类作为参数的可变类构造函数

使用数据构造函数作为函数参数

为每个可变参数模板参数调用函数,并将结果作为构造函数参数传递

Kotlin使用另一个对象作为默认构造函数参数创建新对象

使用作为参数传递的对象创建新对象的构造函数

构造函数使用空值作为参数

使用 decltype 作为构造函数参数

如何访问JavaScript构造函数对象作为IFFI函数参数?

使用扩展对象作为构造函数?

如何使用对象作为构造函数?

SFINAE可变参数构造函数

使用Castle Windsor将具有不同实现的列表的对象作为构造函数参数进行解析

在C ++中使用指向内部类对象的指针作为外部类构造函数参数

Scala - 如何使用接收对象作为参数的构造函数创建类

使用sfinae筛选出首选的可变参数构造函数

如何使用可变参数宏来调用嵌套构造函数?

将对象作为参数传递给构造函数?

在Javascript构造函数中将键/值对象作为参数传递

参数作为对象传递时的 Typescript 构造函数简写

带有对象指针作为参数的C ++复制构造函数

在构造函数中将对象作为参数传递

对象作为参数dectructor调用但不是构造函数?

可变模板,函数作为参数

省略号作为可变参数模板之外的构造函数参数