通常识别 C# 中的模式

Commonly identifying the patterns in C#

我有两个 classes

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

这两个class在另一个class

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

ComponentClass 的数据来自第三方,其中 ClassAClassB[=37 的数据=] 结构相似。 "City" 在 ClassA 中的数据将以逗号分隔值 "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 
}

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

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

您在 json 中的两种类型具有相同的数据类型属性,您可以创建一个 class 来映射它,

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

我建议像您一样从公共基础继承 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; }
    }
}

可能需要将 tenary 重构为 if...elseswitch,具体取决于您是否添加更多类型为 ClassObj 的 类。

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

我用过反射,看看它是否适合你

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