【问题标题】:Commonly identifying the patterns in C#C#中常见的模式识别
【发布时间】:2018-05-18 05:00:35
【问题描述】:

我有两门课

public class ClassA
{
 public int ID { get; set; }
 public string Countries {get;set;}
 public string City { get;set; }
}

public class ClassB
{
 public int ID { get; set; }
 public string Countries {get;set;}
 public string Village{ get;set; }
}

这两个类在另一个类中

public class ComponentClass
{
   public List<ClassA> classAObj { get; set; }
   public List<ClassB> classBObj { get; set; }
}

ComponentClass 的数据来自第三方,ClassAClassB 的数据结构相似。 ClassA 中的 "City" 将具有逗号分隔值的数据 "Manchester,Sydney" 等,与 Village 以及逗号分隔值类似。

现在我正在业务层构建一个自定义对象,我在其中迭代 ComponentClass 的每个属性并提取信息。

Main()
{
  ComponentClass[] c = //Data from 3rd party;
  foreach(var data in c)
  {
    Parent p = new Parent();


    if(data.classAObj.count > 0)
    {
      Star s = new Star();
      s.Area = "infinite";
      s.Color = "red";
      List<string> sep = data.City.Split(',').Select(string.Parse).ToList();    
      foreach(var b in sep)
      {
       TinyStar t = new TinyStar();
       t.smallD = b;
       s.Values.Add(t);
       }
      p.Curves.Add(s);
     }


    if(data.classBObj.count > 0)
    {
      Star s2 = new Star();
      s2.Area = "infinite";
      s2.Color = "red";
      List<string> sep = data.Village.Split(',').Select(string.Parse).ToList();    
      foreach(var b in sep)
      {
       TinyStar t = new TinyStar();
       t.smallD = b;
       s2.Values.Add(t);
       }
      p.Curves.Add(s);
     }

   }
}

在上面的代码中,除了属性名称“City”和“Village”之外,两个 if 语句执行完全相同的操作。我想通过使用我在理论上知道的任何设计模式(可能是策略模式)或任何其他模式来简化这一点。

这是我尝试过的:

public abstract class Base
{
  public int ID { get; set; }
  public string Countries {get;set;}
}

public class ClassA : Base
{

 public string City { get;set; }
}


public class ClassB : Base
{
 public string Village{ get;set; }
}    

我想让它成为一个通用的工厂方法,它将为我执行循环和构建对象以避免重复代码

public void CommonMethod(Base)
{
  // How do I differentiate the properties for looping 
}

【问题讨论】:

  • third party 获取数据的格式是什么?是json吗?
  • 是的,它在 json 中
  • 是否可以选择使用反射?
  • 是的,可以简化不必要的循环两次
  • 你能分享一个json的示例部分吗?

标签: c# .net design-patterns c#-4.0


【解决方案1】:

如果目标是减少代码重复,则可以将两条语句重构为单个操作,如下所示。

foreach(var data in c)
{
    Parent p = new Parent();

    Action<string> iAction = iString =>
    {
        Star s = new Star();
        s.Area = "infinite";
        s.Color = "red";
        List<string> sep = iString.Split(',').Select(string.Parse).ToList();

        foreach(var b in sep)
        {
            TinyStar t = new TinyStar();
            t.smallD = b;
            s.Values.Add(t);
        }
        p.Curves.Add(s);
    }

    if(data.classAObj.count > 0)
    {
        iAction(data.City);
    }

    if(data.classBObj.count > 0)
    {
        iAction(data.Village);
    }
}

【讨论】:

    【解决方案2】:

    对于 json 中的这两种类型,您拥有相同的数据类型属性,而不是您可以创建一个类来映射它,

        public class ClassA
        {
         public int ID { get; set; }
         public string Countries {get;set;}
         public string Areas{ get;set; }
        }
    
    
    public class ComponentClass
    {
       public List<ClassA> classAObj { get; set; }
       public List<ClassA> classBObj { get; set; }
    }
    
    
    Main()
    {
      ComponentClass[] c = //Data from 3rd party;
      foreach(var data in c)
      {
        Parent p = new Parent(); 
        GetParent   (p ,data.classAObj )
        GetParent   (p ,data.classBObj )
       }
    }
    
    void GetParent (Parent p, ClassA classObj){
     if(data.classAObj.count > 0)
        {
          Star s = new Star();
          s.Area = "infinite";
          s.Color = "red";
          List<string> sep = data.Areas.Split(',').Select(string.Parse).ToList();    
          foreach(var b in sep)
          {
           TinyStar t = new TinyStar();
           t.smallD = b;
           s.Values.Add(t);
           }
          p.Curves.Add(s);
         }
    return p ;
    }
    

    【讨论】:

      【解决方案3】:

      我建议像您一样从一个公共基础继承ClassAClassB,然后在类型检查之后强制转换它们。如果您的唯一目标是最小化代码重复,这将助您一臂之力:

      class Program
      {
          static void Main(string[] args)
          {
              ComponentClass[] c = new List<ComponentClass>().ToArray();//Data from 3rd party;
      
              foreach (var data in c)
              {
                  Parent p = new Parent();
      
      
                  if (data.classObjs.Count > 0)
                  {
                      Star s = new Star
                      {
                          Area = "infinite",
                          Color = "red"
                      };
                      foreach (var b in data.classObjs)
                      {
                          string bStr = b.GetType() == typeof(ClassA) ? ((ClassA)b).City : ((ClassB)b).Village;
      
                          bStr = bStr.Split(',').Select(string.Parse).ToList();
      
                          TinyStar t = new TinyStar
                          {
                              smallD = bStr
                          };
                          s.Values.Add(t);
                      }
                      p.Curves.Add(s);
                  }
              }
          }
          public class ComponentClass
          {
              public List<ClassObj> classObjs { get; set; }
          }
      
          public class ClassObj
          {
              public int ID { get; set; }
              public string Countries { get; set; }
          }
      
          public class ClassA : ClassObj
          {
              public string City { get; set; }
          }
      
          public class ClassB : ClassObj
          {
              public string Village { get; set; }
          }
      }
      

      根据您是否添加更多 ClassObj 类型的类,可能需要将三元组重构为 if...elseswitch

      请注意,尽管GetType 实际上会查询程序集(在运行时),但从性能的角度来看应该谨慎使用,因为它在经常执行时会大大降低应用程序的速度。

      【讨论】:

        【解决方案4】:

        我使用了反射,检查它是否适合你

        public static void CommonMethod(dynamic collection)
        {
        
                Parent p = new Parent();
                Star s = new Star();
                s.Area = "infinite";
                s.Color = "red";
                foreach (var data in collection)
                {
                    var properties = data.GetType().GetProperties();
        
                    foreach (var p in properties)
                    {
                        string propertytName = p.Name;
        
                        var propertyValue = p.GetValue(data, null);
        
                        if (propertytName == "City" || propertytName == "Village")
                        {
                            List<string> sep = propertyValue.Split(',').ToList();
                            foreach (var b in sep)
                            {
                                TinyStar t = new TinyStar();
                                t.smallD = b;
                                s.Values.Add(t);
                            }
                            p.Curves.Add(s);
                        }
                    } 
                }
            }
        
            static void Main(string[] args)
            {
                ComponentClass[] c Data from 3rd party;
                foreach (var data in c)
                {
                    CommonMethod(data.classAObj);
                    CommonMethod(data.classBObj);
                }
        }
        

        【讨论】:

          猜你喜欢
          • 2019-03-12
          • 2012-09-17
          • 1970-01-01
          • 2011-08-31
          • 1970-01-01
          • 2011-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多