我一定错过了一些基本的lambdas和代表。这就是..
我有两个功能可以做“几乎”相同的事情。我需要通过将它们写入一个函数并传递“必要的”参数来对它们进行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;
如何通过将上述表达式作为参数传递给上述两个函数?我发现的问题是变量xPoint
和cb
是函数范围内的变量!
这是我尝试过的成功,但在我看来并不优雅:
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;
});
是否有更好的方法来支持他们?
编辑:我试图传递的两个表达式定位了一些动态控件(水平,垂直,对角,曲折等)。该功能已经从4个不同的地方调用,并且可以扩展。为了获得表达式本身,我们从调用类中进行了大量计算。因此,在if else
函数内部(在单独的Utility类中)执行Populate
逻辑并不是我想要的。并且所有方法中唯一的变化是foreach中的定位表达式。所以我正在寻找如何传递这种情况下的论据。
答案 0 :(得分: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
更简洁。
答案 1 :(得分: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通话。
答案 2 :(得分: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);
这是你期待的吗?
答案 3 :(得分: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;
}