如何处理庞大的参数列表?

时间:2011-09-07 00:54:16

标签: c# winforms

所以我的主要课程变得非常大,所以我决定将显示图画封装到自己的班级。

然后,在OnPaint事件处理程序上,我调用displayDrawer.Draw();

唯一的问题是,为了绘制某些东西,该方法需要相当多的参数。

例如,有四个布尔参数指定影响绘图的标志。示例:是否完全绘制(如果未加载文件则不绘制),色调,要绘制的图层等等。当然,还有需要通过的补偿。根据水平和垂直滚动条的偏移量或显示器的宽度和高度,抽屉需要做出相应的反应。

这些都需要传递的原因是因为该类无法访问表单的控件。我宁愿不公开控件或提供访问器,我也不想传递表单。

显而易见的答案是创建一个充满了这样的值的类或结构:

class Offsets
{
    public int horizontal, vertical, displayWidth, displayHeight;

    public Offsets(int horizontal, int vertical, int displayWidth, int displayHeight)
    {
        this.horizontal = horizontal;
        this.vertical = vertical;
        this.displayWidth = displayWidth;
        this.displayHeight = displayHeight;
    }
}

class DrawingFlags
{
    public bool drawCurrentLayer, drawOtherLayers, drawDisplay;

    public DrawingFlags(bool drawCurrentLayer, bool drawOtherLayers, bool drawDisplay)
    {
        this.drawCurrentLayer = drawCurrentLayer;
        this.drawOtherLayers = drawOtherLayers;
        this.drawDisplay = drawDisplay;
    }
}

但它真的值得吗?这些容器在该方法调用期间只能在程序中使用一次,之后只需更多行代码就可以进行筛选。我应该咬紧牙关并接受这一个方法调用有很多参数吗?

5 个答案:

答案 0 :(得分:2)

请注意,如果您只是创建一个具有公共属性的类,但是您使用带有十几个参数的构造函数填充该类,那么您只是将相同的方法参数复杂性从一个地方推到另一个地方,而您通过合并属性增加了更多的复杂性。只有获得净收益才能做到这一点。

例如,你的班级

class Offsets 
{
    public int horizontal, vertical, displayWidth, displayHeight;

    public Offsets(int horizontal, int vertical, int displayWidth, int displayHeight)
    {
        this.horizontal = horizontal;
        this.vertical = vertical;
        this.displayWidth = displayWidth;
        this.displayHeight = displayHeight;
    } 
}

可以修改为如下所示:

class Offsets
{
    public int horizontal { get; set; }
    public int vertical { get; set; }
    public int displayWidth { get; set; }
    public int displayHeight { get; set; }
}

可以像这样填充

var offsets = new Offsets { horizontal = 10, vertical = 20 ... }

这更具可读性,因为您为每个参数指定了名称。它也是智慧的。

请注意,如果您使用的是C#4.0,则不必执行任何此操作,因为您可以获得named and optional parameters的好处:

var result = MyMethod(horizontal: 10, vertical: 20);

答案 1 :(得分:1)

  

但这一切真的值得吗?

是的,当且仅当您最终再次复制相同(或类似)的方法签名或者您必须传入8个以上的参数时,在整个代码中调用该方法。如果它是一个被称为一次或两次的地方的方法,那么我说继续前进,保留当前的参数列表,并且永远不要回头看。

如果您后来确定您有其他类型将遵循类似的模式,那么您应该将选项拆分为复杂类型。您还可以将默认值创建为只读成员,以使默认情况变得容易,但仍然允许在需要它的部分代码中使用不同的行为。

我在工程方面并不擅长,你应该做的事情让你的生活(以及那些追随你......)更容易。对于一种方法,长参数列表可能没问题。如果它在范围内增长,那么就是重构的时候了。

答案 2 :(得分:0)

我认为创建一个类来分组你传递给函数的一堆参数很好,即使它只是在你的应用程序中只使用一次。如果扩展接受类并希望将来将类似的参数传递给子类,这可能很有用。 如果您传递一个参数或二十五个没关系,如果您的参数可以被分组为一个单独的逻辑实体,那么在我看来,一个类绝不是一个糟糕的选择。

如果你真的反对为这样的事情创建一个类,你总是可以使用一个匿名类型......但是我建议你只使用创建类来获得将在灵活性和可扩展性方面提供的好处。将来

答案 3 :(得分:0)

如果您只使用容器类一次,并且仅用于减少应用程序的一个方法中的参数列表,则从7个参数(4个偏移和3个标志)到2个参数(您的两个容器类)那么我会说这不值得。
如果这些容器类在您的应用程序的其他区域中有用,那么它可能是值得的。 .NET框架中有许多方法,包含7个或更多参数。这应该不是问题。

答案 4 :(得分:-2)

另一个想法可能是传递一个词典或类似的东西。我在用Java思考HashMap,但我认为Dictionary是C#中最接近的东西。