【问题标题】:How do I copy two similar lists?如何复制两个相似的列表?
【发布时间】:2018-10-09 13:17:24
【问题描述】:

我有两个列表。只有一个字段差异。如何互相填写列表。

  [Serializable()] 
  public class Lst1
  {
        public string filed1 { get; set; }
        public Int16 filed2 { get; set; }
        .
        .
        .
        public Boolean filed100 { get; set; } 
  }

  [Serializable()] 
  public class Lst2
  {
        public string filed1 { get; set; }
        public Int16 filed2 { get; set; }
        .
        .
        .
        public Boolean filed100 { get; set; } 
        public string filed101 { get; set; }  
  }

List<Lst1> Lst1_ = new List<Lst1>();
List<Lst2> Lst2_ = new List<Lst2>();

我从文件中填写列表。 然后,我需要从列表一中填写列表二,有很多字段并且我不想使用foreach循环。

应该记住,我之前的课程已经构建并序列化并存储在一个文件中。而现在我需要将之前的信息转移到第二个类结构中。

我不想使用这个循环!

foreach (var t in Lst1_)
            {
                Lst2_.Add(new lst2
                {
                    filed1 = t.filed1,
                    filed2 = t.filed2,
                    .
                    .
                    .
                    filed100 = t.filed100,
                    filed101 = "kk"
                }
            }

【问题讨论】:

  • 你能解释更多你想要做什么吗?你尝试了什么?
  • 您的课程有 100-101 个字符串属性?为什么这么多?在我看来,类保存的数据可能更好地表示为列表。
  • 不妨考虑automapper。或者甚至只是将所有这些存储在 string[] 中,似乎这些只是字段和数字,所以数组或 List&lt;T&gt; 对我来说更有意义。
  • 糟糕的班级设计,一个适合所有人
  • 也许类 2 应该从类 1 继承,并且只有一个属性。

标签: c# linq


【解决方案1】:

这是你想要的吗?

class Lst1
{
    public string filed1 { get; set; }
    public string filed2 { get; set; }
    public string filed3 { get; set; }
    public string filed4 { get; set; }
    public string filed5 { get; set; }
}

class Lst2
{
    public string filed1 { get; set; }
    public string filed2 { get; set; }
    public string filed3 { get; set; }
    public string filed4 { get; set; }
    public string filed5 { get; set; }
    public string filed6 { get; set; }
}

void CopyData()
{
        // test data
        List<Lst1> Lst1_ = new List<Lst1>()
        {
            new Lst1()
            {
                filed1 = "1",
                filed2 = "2",
                filed3 = "3",
                filed4 = "4",
                filed5 = "5",
            },
            new Lst1()
            {
                filed1 = "6",
                filed2 = "7",
                filed3 = "8",
                filed4 = "9",
                filed5 = "10",
            },
        };

        List<Lst2> Lst2_ = new List<Lst2>();

        foreach (var item in Lst1_)
        {
            Type type1 = item.GetType();
            PropertyInfo[] properties1 = type1.GetProperties();

            var current = new Lst2();
            Type type2 = current.GetType();
            PropertyInfo[] properties2 = type2.GetProperties();

            int k = 0;
            foreach (PropertyInfo property in properties1)
            {
                var value = property.GetValue(item, null);

                int n; 
                bool isNumeric = int.TryParse(value.ToString(), out n); 
                if (!isNumeric) 
                    value = "Your desired value"; 

                properties2[k].SetValue(current, value);
                k++;
            }

            Lst2_.Add(current);
        }
}

它将列表 1 中的所有内容复制到列表 2。

【讨论】:

  • 如果是你想要的,请在完成后接受它作为答案。
  • 此时:“var value = property.GetValue(item, null);”如果 int32 这样的数字字段是正确的,但如果是字符串则有错误。
  • 我不明白你的意思,你只有字符串属性,哪个数字字段?
  • 对不起,我说错了我的类字段是字符串和数字和布尔值
  • 您的回答绝对正确。只有一个例外,如果两个列表中字段的顺序不同,就会出错。如果我们能够按字段名称对列表进行排序,那就太好了。像这样:foreach (PropertyInfo property in properties1.OrderBy(c=&gt;c.Name))
【解决方案2】:

无需浪费您的时间和金钱,AutoMapper 只需 2 行代码即可为您完成:

using AutoMapper;

namespace ConsoleApp39
{
    class Program
    {
        static void Main (string[] args)
        {
            // fill list1 with data
            var list1 = new List1
            {
                Field1 = "test",
                Field2 = 5,
                Field3 = false,
            };

            // 1) configure auto mapper
            Mapper.Initialize (cfg => cfg.CreateMap<List1, List2> ());

            // 2) create list2 and fill with data from list1
            List2 list2 = Mapper.Map<List2> (list1);

            // fill extra fields
            list2.Field4 = new byte[] { 1, 2, 3 };
        }
    }

    public class List1
    {
        public string Field1 { get; set; }
        public int    Field2 { get; set; }
        public bool   Field3 { get; set; }
    }

    public class List2
    {
        public string Field1 { get; set; }
        public int    Field2 { get; set; }
        public bool   Field3 { get; set; }

        public byte[] Field4 { get; set; } // extra field
    }
}

【讨论】:

    【解决方案3】:

    Lst1 可以继承 Lst2 吗?

    像这样的, 两个列表:

    [Serializable()]
    public class Lst1
    {
        public string filed1 { get; set; }
        public int filed2 { get; set; }
        public bool filed100 { get; set; }
    }
    
    [Serializable()]
    public class Lst2 : Lst1
    {
        public string filed101 { get; set; }
    }
    

    one print extension

    public static class CExtensions
    {
        public static string PropertyList(this Lst1 obj)
        {
            var props = obj.GetType().GetProperties();
            var sb = new StringBuilder();
            foreach (var p in props)
            {
                sb.AppendLine(p.Name + ": " + p.GetValue(obj, null));
            }
            return sb.ToString();
        }
    }
    

    然后使用它:

    class Program
    {
        static void Main(string[] args)
        {
            const int I = 15;
            try
            {
                //init first list
                List<Lst1> Lst1_ = new List<Lst1>();
                Init(Lst1_);
    
                //print it
                Console.WriteLine("Lst1_");
                Console.WriteLine(new string('-', I));
                Lst1_.ForEach(x => Console.WriteLine(x.PropertyList()));
                Console.WriteLine(new string('=', I));
                Console.ReadKey();
    
                //init second list
                List<Lst1> Lst2_ = Lst1_.Cast<Lst1>().ToList(); //equivalent of two next lines
                //List<Lst1> Lst2_ = new List<Lst2>().ConvertAll(x => (Lst1)x);
                //Lst2_.AddRange(Lst1_);
    
                //add one more
                Lst2_.Add(new Lst2
                {
                    filed1 = "101",
                    filed2 = 202,
                    filed100 = true,
                    filed101 = "10100"
                });
    
                //and print 
                Console.WriteLine("Lst2_");
                Console.WriteLine(new string('-', I));
                Lst2_.ForEach(x => Console.WriteLine(x.PropertyList()));
                Console.WriteLine(new string('=', I));
                Console.ReadKey();
    
    
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
            }
        }
    
        private static void Init(List<Lst1> lst_)
        {
            for (int i = 1; i <= 3; i++)
            {
                lst_.Add(new Lst1
                {
                    filed1 = i.ToString(),
                    filed2 = 2 * i,
                    filed100 = i % 2 == 0
                });
            }
        }
    }
    

    享受 =)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-06
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多