用几个if-else语句重构foreach循环

时间:2015-12-09 16:59:24

标签: c#

我已经有了这种方法,如果SPListItem的某个字段为null,我会多次检查,如果是,则为该属性写入默认值。有什么办法可以减少这段代码吗?谢谢

public List<Models.EmployeeInfo> GetEmployeeInfo(SPListItemCollection splic)
{           
    List<Models.EmployeeInfo> listEmployeeInfo = new List<Models.EmployeeInfo>();

    foreach (SPListItem item in splic)
    {               
        var employeeInfo = new Models.EmployeeInfo();

        if (item["EmployeeName"] == null)
        {
            employeeInfo.EmployeeName = "";
        }
        else
        {
            employeeInfo.EmployeeName = item["EmployeeName"].ToString();
        }

        if (item["Position"] == null)
        {
            employeeInfo.Position = "";
        }
        else
        {
            employeeInfo.Position = item["Position"].ToString();
        }

        if (item["Office"] == null)
        {
            employeeInfo.Office = "";
        }
        else
        {
            employeeInfo.Office = item["Office"].ToString();
        }

        if (item["IsPublic"] == null)
        {
            employeeInfo.IsPublic = true;
        }
        else
        {
            employeeInfo.IsPublic = Convert.ToBoolean("IsPublic"); 
        }

        listEmployeeInfo.Add(employeeInfo);
    }

    return listEmployeeInfo;                                           
}

5 个答案:

答案 0 :(得分:1)

尝试类似:

public List<Models.EmployeeInfo> GetEmployeeInfo(SPListItemCollection splic)
{

  var listEmployeeInfo = new List<Models.EmployeeInfo>();
  foreach (SPListItem item in splic)
  {               
    var employeeInfo = new Models.EmployeeInfo();

    employeeInfo.EmployeeName = item["EmployeeName"] == null ? "" : item["EmployeeName"].ToString();

    employeeInfo.Position = item["Position"] == null ? "" : item["Position"].ToString();
    employeeInfo.Office = item["Office"] == null ? "" : item["Office"].ToString();

    employeeInfo.IsPublic = item["IsPublic"] == null || Convert.ToBoolean("IsPublic");

    listEmployeeInfo.Add(employeeInfo);
  }

  return listEmployeeInfo;
}

答案 1 :(得分:1)

您可以使用一些反射来设置属性。 然后,您可以循环遍历所有属性名称的列表并进行设置。 (这种方式将属性添加到模型中时,您需要做的就是将其添加到字符串列表中)

public List<Models.EmployeeInfo> GetEmployeeInfo(SPListItemCollection splic)
{
    var listEmployeeInfo = new List<Models.EmployeeInfo>();
    var propertyNames = new List<string>(){"EmployeeName","Position","Office","IsPublic"}

    foreach (SPListItem item in splic)
    {
        var employeeInfo = new Models.EmployeeInfo(); 

        foreach (var propertyName in propertyNames)
        {  
            string newData = "";
            if (item[propertyName] != null)
            {
                newData = item[propertyName];
            }
            employeeInfo.GetType().GetProperty(propertyName).SetValue(employeeInfo, newData, null); 
        }

        listEmployeeInfo.Add(employeeInfo);
    }
    return listEmployeeInfo;
}

答案 2 :(得分:0)

尝试将公共逻辑重构为函数。

employeeInfo.EmployeeName = ConditionalToString(item, "EmployeeName");
employeeInfo.Position = ConditionalToString(item, "Position");
employeeInfo.Office = ConditionalToString(item, "Office");
employeeInfo.IsPublic = item[attrName] == null ? false : Convert.ToBoolean("IsPublic");

string ConditionalToString(SPListItem item, string attrName)
{
    return (item[attrName] == null ? "" : item[attrName].ToString());
}

null coalesce operator无法使用,因为[attrName]和“”项是不同的类型,所以这样的内容不起作用:(item[attrName] ?? "").ToString()dynamic会对此有所帮助案例?我不经常使用它。)

TLJ's comment是可以发生这种逻辑的替代解决方案(虽然你仍然会有相同的重复)。

答案 3 :(得分:0)

我同意这里给出的另一个使用三元运算符的答案。奇怪的是,昨天我正在研究同样的事情。你可以而且应该在这里使用三元运算符而不是 if - else

<强>优点吗

  • 首先,它会使代码更短,让您一目了然。
  • 更大的优势在于......您当前的代码是基于陈述的。所以你正在做的是你正在测试一个条件并执行语句作为该条件的副作用但是当使用三元运算符时,你使用表达式计算结果 (这正是你想要做的 - 你试图生成你的employeeInfo对象列入清单)。
  • 在每个属性的当前设计中,您有2个位置分配了其值( if 块和 else 块)。使用三元运算符时,仅在一个位置分配值。

此外,您可以将employeeInfo对象创建重构为另一种方法并保持当前方法更清晰(如下所示):

public List<Models.EmployeeInfo> GetEmployeeInfo(SPListItemCollection splic)
{
    var listEmployeeInfo = new List<Models.EmployeeInfo>();
    foreach (SPListItem splicItem in splic)
    {               
      listEmployeeInfo.Add(CreateEmployeeInfoFromItem(splicItem));
    }
    return listEmployeeInfo;
}

private static Models.EmployeeInfo CreateEmployeeInfoFromItem(SPListItem item)
{
    var employeeInfo = new Models.EmployeeInfo();
    employeeInfo.EmployeeName = item["EmployeeName"] == null ? "" : item["EmployeeName"].ToString();
    employeeInfo.Position = item["Position"] == null ? "" : item["Position"].ToString();
    employeeInfo.Office = item["Office"] == null ? "" : item["Office"].ToString();
    employeeInfo.IsPublic = item["IsPublic"] == null || Convert.ToBoolean("IsPublic");
    return employeeInfo;
}

答案 4 :(得分:0)

我会考虑创建一个映射对象,它自己负责从给定的SPListItem实例创建一个EmployeeInfo实例。在这个映射对象中,您将拥有验证标准/设置标准,然后只要您有这个需求,就可以使用一个很好的映射对象来完成工作。

public class SPListItemToEmployeeInfoMapper
{
    public static Models.EmployeeInfo Map(SpListItem item);
    { //your logic here to create the employeeinfo from SpListItem }
}

然后你的来电者:

public List<Models.EmployeeInfo> GetEmployeeInfo(SPListItemCollection splic)
{
   var listEmployeeInfo = new List<Models.EmployeeInfo>();
   foreach (SPListItem splicItem in splic)
   {               
      listEmployeeInfo.Add(SPListItemToEmployeeInfoMapper.Map(splicItem));
   }
   return listEmployeeInfo;
}