Как сократить два метода с той же тематикой?


У меня есть этот код:

private void numWidth_ValueChanged(object sender, EventArgs e)
{
    if (ignoreChange) return; // Sometimes I only want to change the value without the event firing (like when undo-ing)

    PushUndoStack();

    int width = (int)numWidth.Value;

    foreach (Layer layer in doc.TileLayers)
        layer.Width = width;

    hscDoc.Maximum = doc.WidthInPixels;
    ClampScrollbarValue(hscDoc);
}

private void numHeight_ValueChanged(object sender, EventArgs e)
{
    if (ignoreChange) return;

    PushUndoStack();

    int height = (int)numHeight.Value;

    foreach (Layer layer in doc.TileLayers)
        layer.Height = height;

    vscDoc.Maximum = doc.HeightInPixels;
    ClampScrollbarValue(vscDoc);
}

Они оба очень похожи, но я не могу придумать хороший способ, чтобы объединить два. Это происходит несколько раз в моей программе и строк кода действительно растут. Я полагаю, я мог бы использовать отражение, но это перебор? Кто-нибудь может придумать лучшего способа?

Это просто пример. Это происходит несколько раз в моей программе, где функции очень схожи, но не может быть легко преобразована в универсальный метод.



315
5
c#
задан 31 августа 2011 в 10:08 Источник Поделиться
Комментарии
3 ответа

Что-то вдоль этих линий:

private void ValueChangedImp(object sender, EventArgs e, Func<int> get_value, Action<Layer, int> set_value, Func<int> get_pixels)
{
if (ignoreChange) return; // Sometimes I only want to change the value without the event firing (like when undo-ing)

PushUndoStack();

int value = get_value();

foreach (Layer layer in doc.TileLayers)
set_value(laywe, value);

hscDoc.Maximum = get_pixels();
ClampScrollbarValue(hscDoc);
}

private void numWidth_ValueChanged(object sender, EventArgs e)
{
ValueChangedImp(sender, e, () => (int)numWidth.Value, (layer, value) => layer.Width = value, () => doc.WidthInPixels);
}

private void numHeight_ValueChanged(object sender, EventArgs e)
{
ValueChangedImp(sender, e, () => (int)numHeight.Value, (layer, value) => layer.Height = value, () => doc.HeightInPixels);
}

5
ответ дан 31 августа 2011 в 11:08 Источник Поделиться

Вы можете попробовать эту идею ниже.

    private void numWidth_ValueChanged(object sender, EventArgs e)
{
if (OnValueChanged((layer, value) => layer.Width = value, (int)numWidth.Value))
{
// Can be refactored in a similar
// hscDoc.Maximum = doc.WidthInPixels;
// ClampScrollbarValue(hscMap);
}
}

private void numHeight_ValueChanged(object sender, EventArgs e)
{
if (OnValueChanged((layer, value) => layer.Height = value, (int)numHeight.Value));
{
// Can be refactored in a similar way
// vscDoc.Maximum = doc.HeightInPixels;
// ClampScrollbarValue(vscMap);
}
}

private bool OnValueChanged<TValue>(Action<Layer, TValue> setter, TValue value)
{
if (ignoreChange) return false;

PushUndoStack();

foreach (Layer layer in doc.TileLayers)
setter(layer, value);

return true;
}

2
ответ дан 31 августа 2011 в 11:08 Источник Поделиться

в то время как другие решения показывают способы внедрения кода в функцию шаблона, что полезно. Но может привести к случайным соединение'. Его хороший подход в некоторых ситуациях.

Но, возможно, я бы выбрал...

Я бы тоже, наверное, работать, чтобы двигаться UpdateDimensions к модели представления и для того, чтобы взять высоту и ширину в качестве параметра.

private void numWidth_ValueChanged(object sender, EventArgs e)
{
UpdateDimensions();
}
private void numHeight_ValueChanged(object sender, EventArgs e)
{
UpdateDimensions();
}

private void UpdateDimensions()
{
if (ignoreChange) return;
PushUndoStack();

int width = (int)numWidth.Value;
int height = (int)numHeight.Value;

foreach (Layer layer in doc.TileLayers)
{
layer.Width = width;
layer.Height = height;
}
hscDoc.Maximum = doc.WidthInPixels;
ClampScrollbarValue(hscDoc);
vscDoc.Maximum = doc.HeightInPixels;
ClampScrollbarValue(vscDoc);
}

2
ответ дан 1 сентября 2011 в 10:09 Источник Поделиться