删除“if”时出现问题陈述

发布于 2024-11-27 12:16:55 字数 1880 浏览 0 评论 0原文

您好,

我正在尝试找到改进此代码的方法。 我想从 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();
    }
  }

谢谢,

Hi,

I'm trying to find way how to improve this code.
I would like to remove "if" statement from CreateAttributes method.
The main idea of this method to add attribute to list if this attribute satisfies some conditions

  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();
    }
  }

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

时光是把杀猪刀 2024-12-04 12:16:55

您可以在此处使用多态性

  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();
}

You can use polymorphism here

  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
    }
  }

create other classes for other types

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();
}
旧人哭 2024-12-04 12:16:55

案例切换会更好:

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

a case switch would be better:

switch (item.Type)
{
    case typeof(string):
        // code here
       break;
    case typeof(DateTime):
        // code here
       break;
    case typeof(bool):
        // code here
       break;
}
西瑶 2024-12-04 12:16:55

我认为最好重构你的代码如下:

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();
    }
}

I think its better to refactor your code as follow:

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();
    }
}
魔法少女 2024-12-04 12:16:55

您可以构建类型和整数之间的映射。然后您可以打开查找结果。 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 所有。

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

You could build a map between types and integers. Then you could switch on the result of the lookup. On SO is another question with that approach posted.

A copied part of one of the answers:

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;
    }
}

Credits for that code goes to bjax-bjax.

Maybe you could think of wrapping the lookup to a function to return a default value.

め可乐爱微笑 2024-12-04 12:16:55

第一个质量改进是使用else if。对于发布的示例来说,这意味着同样的事情,但更清晰一些。

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

例如,

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

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

        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通常是一个不错的选择。通常,忍受使用 if 比忍受缺乏编译时类型检查(使用字符串方法的 switch 可能会导致这种情况)更为明智。即,如果弄错一个字母,您的 switch 语句似乎不再那么酷了。

如果每个条件分支内发生一些通用的事情,还有其他选择。

the first quality improvement would be to use else if. It will mean the same thing for the example posted, but be a little clearer.

For this kind of thing I prefer using if

e.g.

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

The main alternative is switch (don't do the below because it'll fail):

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

but this results in:

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

Which means you need an extra level on indirection. Like you tag each class through an interface e.g. IMyTag which returns an enum of some kind, or you assign ids to each type via a helper function.

Seriously, if is normally not a bad choice for this kind of thing. Often it's smarter to endure using an if than to endure the lack of compile-time type checking that can result from a switch using a string approach. i.e. get one letter wrong and your switch statement doesn't appear to be quite so cool any more.

If there's something generic going on inside each conditional branch, there are other options.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文