首页 新闻 会员 周边

C# 怎么深克隆一个List?

0
悬赏园豆:20 [已解决问题] 解决于 2020-08-11 09:46

例如

Tag.cs

using System.Drawing;

namespace TestApp
{
    class Tag
    {
        private string name;
        private int size;

        public Tag(string name,int size)
        {
            this.name = name;
            this.size = size;
        }
        public string Getname()
        {
            return name;
        }

        public void Setname(string value)
        {
            name = value;
        }

        public int GetSize()
        {
            return size;
        }

        public void SetSize(int value)
        {
            size = value;
        }
    }
}

Program.cs


    static void Main()
    {
        List<Tag> list = new List<Tag>();
        list.Add(new Tag("tag", 100));
        list.Add(new Tag("tagger", 1000));
        list.Add(new Tag("tager", 500));
        list.Add(new Tag("tag", 200));

        //List<Tag> listClone = list???这个该怎么写?
    }

我在网上找了好多,但是他们都是代码片段,就只是一个方法,我也不知道加在那里,试出来的结果也不对。

现在就是想要一个深克隆的例子,比较全的

echo_lovely的主页 echo_lovely | 小虾三级 | 园豆:1433
提问于:2020-08-11 09:15
< >
分享
最佳答案
0
收获园豆:10
RosonJ | 老鸟四级 |园豆:4910 | 2020-08-11 09:37

你这个.tw我可能。。。

echo_lovely | 园豆:1433 (小虾三级) | 2020-08-11 09:39

打不开,哈哈,你的10个园豆要泡汤

会长 | 园豆:12401 (专家六级) | 2020-08-11 09:41

@小草上飞飞:
Solution A

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public static class CommonExtensions
{

    /// <summary>
    /// 深層複製(複製對象須可序列化)
    /// </summary>
    /// <typeparam name="T">複製對象類別</typeparam>
    /// <param name="source">複製對象</param>
    /// <returns>複製品</returns>
    public static T DeepClone<T>(this T source)
    {

        if (!typeof(T).IsSerializable)
        { 
            throw new ArgumentException("The type must be serializable.", "source"); 
        }

        if (source != null)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                var formatter = new BinaryFormatter();
                formatter.Serialize(stream, source);
                stream.Seek(0, SeekOrigin.Begin);
                T clonedSource = (T)formatter.Deserialize(stream);
                return clonedSource;
            }
        }
        else
        { return default(T); }

    }
  
}

Solution B

using Newtonsoft.Json;

public static class CommonExtensions
{

    /// <summary>
    /// 深層複製(需使用Json.Net組件)
    /// </summary>
    /// <typeparam name="T">複製對象類別</typeparam>
    /// <param name="source">複製對象</param>
    /// <returns>複製品</returns>
    public static T DeepCloneViaJson<T>(this T source)
    {

        if (source != null)
        {
            // avoid self reference loop issue
            // track object references when serializing and deserializing JSON
            var jsonSerializerSettings = new JsonSerializerSettings
            {
                PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                TypeNameHandling = TypeNameHandling.Auto
            };

            var serializedObj = JsonConvert.SerializeObject(source, Formatting.Indented, jsonSerializerSettings);
            return JsonConvert.DeserializeObject<T>(serializedObj, jsonSerializerSettings);
        }
        else
        { return default(T); }
     
    }
  
}

使用
img

RosonJ | 园豆:4910 (老鸟四级) | 2020-08-11 09:43

@会长:
唉~還得搬代碼

RosonJ | 园豆:4910 (老鸟四级) | 2020-08-11 09:44

@RosonJ: 我豆危矣.......

会长 | 园豆:12401 (专家六级) | 2020-08-11 09:46

@RosonJ: 啊,也分了我10个园豆,楼主好人

会长 | 园豆:12401 (专家六级) | 2020-08-11 09:48

@会长:
你10個,我10個,還行吧

RosonJ | 园豆:4910 (老鸟四级) | 2020-08-11 09:48

@RosonJ: 你们都那么多豆了,还瓜分我,大清要亡

echo_lovely | 园豆:1433 (小虾三级) | 2020-08-11 09:51

@小草上飞飞:
豆子還好,我比較想要聲望哈哈哈

RosonJ | 园豆:4910 (老鸟四级) | 2020-08-11 09:52

@RosonJ: MemoryStream stream = new MemoryStream()这个流不用 close() 吗?

echo_lovely | 园豆:1433 (小虾三级) | 2020-08-11 11:02

@小草上飞飞:
用using的方式會自動close

RosonJ | 园豆:4910 (老鸟四级) | 2020-08-11 11:04
其他回答(1)
0
using System;
using System.Collections.Generic;

namespace ConsoleApp5
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Tag> list = new List<Tag>
            {
                new Tag("a", 1),
                new Tag("b", 2),
            };

            var list2 = CloneList(list);

            foreach (var item in list)
            {
                item.Size += 1;
                item.Name += "a";
            }
            Console.WriteLine("list");
            PrintList(list);
            Console.WriteLine("list2");
            PrintList(list2);
            Console.ReadLine();
        }

        private static List<Tag> CloneList(List<Tag> list)
        {
            List<Tag> newList = new List<Tag>();
            foreach (var item in list)
            {
                newList.Add(item.Clone() as Tag);
            }

            return newList;
        }

        private static void PrintList(List<Tag> list)
        {
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
        }
    }

    class Tag: ICloneable
    {
        public Tag(string name, int size)
        {
            Size = size;
            Name = name;
        }

        public int Size { get; set; }

        public string Name { get; set; }

        public object Clone()
        {
            return new Tag(Name, Size);
        }

        public override string ToString()
        {
            return $"Name:{Name};Szie:{Size}";
        }
    }
}

收获园豆:10
会长 | 园豆:12401 (专家六级) | 2020-08-11 09:39

另一种呢?就是用[Serializable]这个标签的

支持(0) 反对(0) echo_lovely | 园豆:1433 (小虾三级) | 2020-08-11 09:43

@小草上飞飞: 那是把对象先序列化了然后再反序列化吧,也不错

支持(0) 反对(0) 会长 | 园豆:12401 (专家六级) | 2020-08-11 09:44
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册