通常在C#中识别模式

时间:2018-05-18 05:00:35

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

我有两个班级

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 的数据来自第三方,其中 ClassA ClassB 的数据结构相似。 ClassA中的“City”将使用逗号分隔值“曼彻斯特,悉尼”等数据,类似于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 
}

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我建议你继续从公共基础继承 <div class="form-group required"> <input id="autocomplete" name="driver[]" class="form-control" value = "{{place.name}}"/> </div> var userlist = {{ lusers| json_encode | raw }}; var datasource = [{"label" : userlist.name, "value" : userlist.id}]; $('#autocomplete').autocomplete({ source:datasource }); ,然后在类型检查后继续投射它们。如果您的唯一目标是最大限度地减少代码重复,那么您将获得:

ClassA

根据您是否添加更多类型为ClassB的类,可能需要将契约重构为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; } } } if...else

虽然switch实际上会查询程序集(在运行时),但是从性能的角度来看应该谨慎使用,因为它会在经常执行时大大减慢应用程序的速度。

答案 3 :(得分:0)

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

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