如何重构这段代码?

4
我该如何重构这段代码,使其只有一个方法或者其他什么方式?
            if (!string.IsNullOrEmpty(_gridModel.Header))
                _gridModel.Header += ",";
            if (item != null)
                _gridModel.Header += item.Header;

            if (!string.IsNullOrEmpty(_gridModel.Width))
                _gridModel.Width += ",";
            if (item != null)
                _gridModel.Width += item.Width;

            if (!string.IsNullOrEmpty(_gridModel.Align))
                _gridModel.Align += ",";
            if (item != null)
                _gridModel.Align += item.Align;

            if (!string.IsNullOrEmpty(_gridModel.Filter))
                _gridModel.Filter += ",";
            if (item != null)
                _gridModel.Filter += item.Filter;

            if (!string.IsNullOrEmpty(_gridModel.Type))
                _gridModel.Type += ",";
            if (item != null)
                _gridModel.Type += item.Type;

            if (!string.IsNullOrEmpty(_gridModel.Sort))
                _gridModel.Sort += ",";
            if (item != null)
                _gridModel.Sort += item.Sort;
2个回答

15
首先,将逻辑重构为一个函数。
_gridModel.Header = AppendItem(_gridModel.Header, item == null ? null : item.Header);
_gridModel.Width = AppendItem(_gridModel.Width, item == null ? null : item.Width);
...
...

string AppendItem(string src, string item)
{
 if (! string.IsNullOrEmpty(src))
  src += ",";
 if (! string.IsNullOrEmpty(item))
  src += item;
 return src;
}

一个不错的下一步,是使用反射和属性:

编辑:完善了反射解决方案,尽管还没有调试。

AppendProperties(_gridModel, item, "Header", "Width", "Align", ...)

void AppendProperty(object gridmodel, object item, params string[] propNames)
{
    foreach (string propName in propNames)
        AppendProperties(gridmodel, item, propName);
}

void AppendProperties(object gridmodel, object item, string propName)
{
    PropertyInfo piGrid = gridmodel.GetType().GetProperty(propName);
    if (piGrid != null && piGrid.PropertyType == typeof(string))
    {
        piGrid.SetValue(gridmodel, 
            piGrid.GetValue(gridmodel, null).ToString() + ",", null);
    }

    if (item == null) return;
    PropertyInfo piItem = item.GetType().GetProperty(propName);
    if (piItem != null)
    {
        piGrid.SetValue(gridmodel, 
            piGrid.GetValue(gridmodel, null).ToString() 
            + piItem.GetValue(item, null).ToString(), 
            null);
    }
}

+1 已经足够接近了,我可能会使用 (ref string src, ...) 并且不返回该值。 - csharptest.net
可能会更快,但我倾向于在可能的情况下不产生副作用。 - Alan Jackson
在调用item.Header时出现了NullReferenceException异常:AppendItem(_gridModel.Header, item.Header); - eglasius
我喜欢你的第一步,我认为它实际上比被接受的答案更好。然而,在这种情况下使用反射和魔术字符串,在我看来有点过头了。 - Jeremy Roberts
Freddy:在调用函数时添加了对项目为空的检查,谢谢。 - Alan Jackson

7
假设您已经安装了.NET 3.5:
string Filter(string input, SomeType item, Func<SomeType, string> extract)
{
    if (!String.IsNullOrEmpty(input))
    {
        if (item == null) return ",";
        else return "," + extract(item);
    }
}

_gridModel.Header += Filter(_gridModel.Header, item, i => i.Header);
_gridModel.Width += Filter(_gridModel.Width, item, i => i.Width);
_gridModel.Align += Filter(_gridModel.Align, item, i => i.Align);

// etc...

完美!-- 正是我在寻找的。 - CurlyFro
3
根据您的用途,如果有很多追加操作,使用StringBuilder可能会提供更好的性能。 - sooniln
哦,如果它在循环中,传递一个字符串构建器可能比连接更有意义。 - Tamas Czinege

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接