删除";如果";声明

本文关键字:quot 声明 如果 删除 | 更新日期: 2023-09-27 18:04:15

嗨,

我正在设法改进这段代码。我想从CreateAttributes方法中删除"if"语句。如果属性满足某些条件,则将该属性添加到列表的方法的主要思想是

  internal class FildMap
  {
    public string ExactTargetFild { get; set; }
    public string DbFild { get; set; }     
    public Type Type { get; set; }
  }
  internal static class FildMapProcessor
  {
    private static readonly List<FildMap> Map = new List<FildMap>();
    static FildMapProcessor()
    {
      if(Map.Count == 0)
      {
      Map.Add(new FildMap {ExactTargetFild = "Address 1", DbFild = "Address1", Type = typeof (string)});
      Map.Add(new FildMap { ExactTargetFild = "Date of birth", DbFild = "DateOfBirth", Type = typeof(DateTime) });
      Map.Add(new FildMap { ExactTargetFild = "Wine Beer", DbFild = "pref_WineBeerSpirits", Type = typeof(bool) });
      .........
      }
    }
    public static Attribute[] CreateAttributes(this DataRow row)
    {
      var attributes = new List<Attribute>();
      foreach (var item in Map)
      {
        if (item.Type == typeof(string))
        {
          var value = row.Get<string>(item.DbFild);
          if (value != null)
            attributes.Add(new Attribute{Name = item.ExactTargetFild, Value = value});
        }
        if (item.Type == typeof(DateTime))
        {
          var value = row.Get<DateTime>(item.DbFild);
          if (value != DateTime.MinValue)
            attributes.Add(new Attribute { Name = item.ExactTargetFild, Value = value.ToString("dd/MM/yyyy") });
        }
        if (item.Type == typeof(bool))
        {
          if (row.Contains(item.DbFild))
          {
            var value = row.Get<bool>(item.DbFild);
            attributes.Add(new Attribute { Name = item.ExactTargetFild, Value = value.ToString() });
          }
        }
      }
      return attributes.ToArray();
    }
  }

谢谢,

删除";如果";声明

您可以在这里使用多态性

  internal abstract class FildMap
  {
    public string ExactTargetFild { get; set; }
    public string DbFild { get; set; }     
    public abstract List<Attributes> GetAttributes(DataRow row);
  }
  internal class StringFildMap : FildMap
  { 
    public override List<Attributes> GetAttributes(DataRow row)
    {
      //string specific stuff
    }
  }

为其他类型的创建其他类

public static Attribute[] CreateAttributes(this DataRow row)
{
  var attributes = new List<Attribute>();
  foreach (var item in Map)
  {
    attributes.AddRange(item.GetAttributes(row)); 
  }
  return attributes.ToArray();
}

情况切换会更好:

switch (item.Type)
{
    case typeof(string):
        // code here
       break;
    case typeof(DateTime):
        // code here
       break;
    case typeof(bool):
        // code here
       break;
}

我认为最好按照以下方式重构代码:

internal class FildMap
{
    public string ExactTargetFild { get; set; }
    public string DbFild { get; set; }
    public Type Type { get; set; }
    public  object GetValue(object value)
    {
        switch(Type.Name)
        {
            case "System.String":
                // [Code]
                break;
            case "System.DateTime":
                // [Code]
                break;
            case "System.Boolean":
                // [Code]
                break;
        }
        return null;
    }

}
internal static class FildMapProcessor
{
    private static readonly List<FildMap> Map = new List<FildMap>();
    static FildMapProcessor()
    {
        if (Map.Count == 0)
        {
            Map.Add(new FildMap { ExactTargetFild = "Address 1", DbFild = "Address1", Type = typeof(string) });
            Map.Add(new FildMap { ExactTargetFild = "Date of birth", DbFild = "DateOfBirth", Type = typeof(DateTime) });
            Map.Add(new FildMap { ExactTargetFild = "Wine Beer", DbFild = "pref_WineBeerSpirits", Type = typeof(bool) });
        }
    }
    public static Attribute[] CreateAttributes(this DataRow row)
    {
        var attributes = new List<Attribute>();
        foreach (var item in Map)
        {
            foreach (var item in Map)
            {
                var value = item.GetValue(row[item.DbFild]);
                if(value != null)
                    attributes.Add(new Attribute { Name = item.ExactTargetFild, Value = value });
            }
        }           
        return attributes.ToArray();
    }
}

您可以在类型和整数之间构建映射。然后您可以打开查找结果。关于SO是另一个问题,发布了这种方法。

其中一个答案的复制部分:

Dictionary<Type, int> typeDict = new Dictionary<Type, int>
{
    {typeof(int),0},
    {typeof(string),1},
    {typeof(MyClass),2}
};
void Foo(object o)
{
    switch (typeDict[o.GetType()])
    {
        case 0:
            Print("I'm a number.");
            break;
        case 1:
            Print("I'm a text.");
            break;
        case 2:
            Print("I'm classy.");
            break;
        default:
            break;
    }
}

该代码归功于bjax-bjax。

也许您可以考虑将查找封装到一个函数中以返回默认值。

第一个质量改进是使用else-if。对于发布的示例来说,这将意味着相同的事情,但要更清楚一点。

对于这种事情,如果,我更喜欢使用

例如

if(){
} 
else if {
} 
else if {
} else {
}

主要的替代方案是切换(不要执行以下操作,因为它会失败(:

        switch(typeof(PingItemRequestQrMsg))
        {
            case typeof(string):
                break;
        }

但这会导致:

        Error   1   A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable

这意味着你需要一个额外的间接级别。就像您通过接口标记每个类一样,例如返回某种枚举的IMyTag,或者您通过助手函数为每个类型分配id。

说真的,如果通常是一个不错的选择。通常,忍受使用if比忍受使用字符串方法切换可能导致的编译时类型检查不足更明智。也就是说,如果一个字母错了,你的switch语句就不再那么酷了。

如果每个条件分支内部都有一些通用的东西,那么还有其他选项。