0

我一定错过了 lambda 和委托的一些基础知识。来了。。

我有两个功能“几乎”相同的事情。我需要通过将它们写入一个函数并传递“必要”参数来对它们进行 OOP。

这两个函数大致是这样的:

private static bool Populate1(int yPoint)
{
    //---------------------------------
    //--------------------------------
    int xPoint = 0;

    foreach (var item in collection)
    {
        ComboBox cb = AddControl_Combo(item, xPoint, yPoint);

        xPoint += cb.Width + 12;
        yPoint = 0;
    }

    //-------------------------------
    //-------------------------------

    return true;
}

private static bool Populate2(int yPoint)
{
    //---------------------------------
    //--------------------------------
    int xPoint = 0;

    foreach (var item in collection)
    {
        ComboBox cb = AddControl_Combo(item, xPoint, yPoint);

        yPoint += cb.Height + 12;
    }

    //---------------------------------
    //--------------------------------

    return true;
}

这些函数要冗长得多,所以我真的想把它们干掉。可以注意到,这两个函数的唯一区别是两个定位函数

xPoint += cb.Width + 12;
yPoint = 0;

yPoint += cb.Height + 12;

如何通过将上述表达式作为参数将上述两个函数合二为一?我发现的问题是变量xPointcb是函数范围内的变量!

这是我尝试并成功的方法,但在我看来并不优雅:

private static bool Populate(ref int xPoint, ref int yPoint, ref ComboBox cb, 
                              Action positioningFunc)
{
    foreach (var item in collection)
    {
        cb = AddControl_Combo(item, xPoint, yPoint);

        positioningFunc();
    }

    return true;
}

并称之为:

int xPoint = 0;
int yPoint = 0;
ComboBox cb = null;
return Populate(ref xPoint, ref yPoint, ref cb, () =>
{
    xPoint += cb.Width + 12;
    yPoint = 0;
});

int xPoint = 0;
int yPoint = 19;
ComboBox cb = null;
return Populate(ref xPoint, ref yPoint, ref cb, () =>
{
    yPoint += cb.Height + 12;
});

有没有更好的方法来 OOP 他们?

编辑:我试图传递位置的两个表达式是一些动态控件(水平、垂直、对角线、之字形等)。该函数已经从 4 个不同的地方调用并且可以扩展。为了获得表达式本身,我们从调用类中进行了大量计算。所以在函数if else内部做一个逻辑Populate(在一个单独的实用程序类中)不是我想要的。所有方法中唯一的变化是foreach中的那些定位表达式。所以我正在寻找在这种情况下如何传递参数。

4

4 回答 4

2

如果您需要通过 Lambdas 完成,这里有一个替代方案:

 private static bool Populate(int yPoint, Func<ComboBox, Point, Point> modifier)
 {
    var point = new Point (0, yPoint);
    foreach (var item in collection)
    {
        ComboBox cb = AddControl_Combo(item, point.X, point.Y);
        point = modifier(cb, point);
    }
    return true;
}

这两个电话将是:

Populate(0, (cb, point) => new Point(point.X + cb.Width + 12, 0));
Populate(0, (cb, point) => new Point(0, point.Y + cb.Height + 12));

您也可以使用Tuple<int, int>Point更简洁。

于 2012-07-05T00:19:21.670 回答
1

简单的逻辑

private static bool Populate(int yPoint, bool flag)
{
    int xPoint = 0;

    foreach (var item in collection)
    {
        var ComboBox cb = AddControl_Combo(item, xPoint, yPoint);

        if(flag)
        {
            xPoint += cb.Width + 12;
            yPoint = 0;
        }
        else
        {
            yPoint += cb.Height + 12;
        }
    }

    return true;
}

当您需要 Populate1 时,请调用Populate(valueofypoint, true)Populate(valueofypoint, false)为 Populate2 调用。

于 2012-07-05T00:04:22.623 回答
1

这应该完全按照您的需要工作:

private static bool Populate(int yPoint,
    Func<int, ComboBox, int> xStep,
    Func<int, ComboBox, int> yStep)
{
    int xPoint = 0;

    foreach (var item in collection)
    {
        ComboBox cb = AddControl_Combo(item, xPoint, yPoint);

        xPoint = xStep(xPoint, cb);
        yPoint = yStep(xPoint, cb);
    }

    return true;
}

你只是这样称呼它:

Populate(42, (x, cb) => x + cb.Width + 12, (y, cb) => 0);
Populate(42, (x, cb) => 0, (y, cb) => y + cb.Width + 12);

这是你所期待的吗?

于 2012-07-05T00:40:14.390 回答
0

结合您的想法和 Nikhil 的建议:

private static bool Populate(int yPoint, int position)
{
    int xPoint = 0;

    ComboBox cb;

    Action positionFunction;
    if (position == 1)
    {
            positionFunction = () => { 
                    xPoint += cb.Width + 12;
                    yPoint = 0;
            };
    }
    else if (position ==2)
    {
            positionFunction = () => { yPoint += cb.Height + 12; };
    }
    else
    {
            throw new Exception("Invalid position");
    }

    foreach (var item in collection)
    {
        cb = AddControl_Combo(item, xPoint, yPoint);

        positionFunction();
    }

    return true;
}
于 2012-07-05T00:13:44.630 回答