复制不支持复制功能的动态对象的最快方法

Gre*_*mar 8 .net c# optimization copy

首先,我们可能都同意最好的方法是在自定义对象/实体中实现复制功能.但请考虑这种情况.我们没有这个选项,我们不想编写将生成实体的精确副本的特定函数,因为将来实体将被更改,因此我们的复制函数将失败.

这是当前实体的简化版本:

[Serializable]
class MyEntity
{
    public MyEntity()
    { 
    }

    public MyEntity(int id, string name)
    {
        this.Id = id;
        this.Name = name; 
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public MyEntity Copy()
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

为了满足上述所有要求,我提出了两个解决方案:

        //original...
        MyEntity original = new MyEntity() { Id = 1, Name = "demo1" };

        //first way to copy object...
        List<MyEntity> list = new List<MyEntity>() { original};
        MyEntity copy1 = list.ConvertAll(entity => new MyEntity(entity.Id, entity.Name))[0];

        //second way to copy object...
        byte[] bytes = SerializeEntity(original);
        MyEntity copy2 = (MyEntity)DeserializeData(bytes);


    byte[] SerializeEntity(object data)
    {
        byte[] result = null;
        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, data);
            result = ms.ToArray();
        }
        return result;
    }

    object DeserializeData(byte[] data)
    {
        object result = null;
        using(MemoryStream ms = new MemoryStream(data))
        {
           BinaryFormatter formatter = new BinaryFormatter();
           result = formatter.Deserialize(ms); 
        }
        return result;
    }
Run Code Online (Sandbox Code Playgroud)

而现在的问题.什么解决方案是幕后最优秀的,为什么,第一或第二?考虑到上述要求,有没有更好的方法来进行精确复制?副本将大量完成.

PS注意: 我知道第一种方式基本上已经是Honza指出的复制功能.我有点像序列化一样多功能,而且接近快速自定义复制功能.

pes*_*ino 7

首先,我们可能都同意最好的方法是在自定义对象/实体中实现复制功能.

我不同意.我不想每次都写这样的方法.以下是我使用扩展方法的建议:

public static T Copy<T>(this T obj)
    where T : class
{
    using (MemoryStream stream = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, obj);

        stream.Seek(0, SeekOrigin.Begin);
        return formatter.Deserialize(stream) as T;
    }
}
Run Code Online (Sandbox Code Playgroud)

这基本上是您的第二个解决方案,但略有优化 无需将MemoryStream复制到字节数组,然后从中创建另一个MemoryStream.

最好的是它是通用的,可以与具有该[Serializable]属性的每个对象一起使用.而且我很确定它比你必须访问每个属性的第一个解决方案更快(尽管我没有测量).

编辑:

好的,我实际上现在做了一些测量.我对表演的第一个假设是完全错误的!

我用随机值创建了1000000个MyEntity对象,然后复制它们(我还考虑Honza Brestan了深层和浅层副本的提示):

使用二进制格式化程序进行
深度复制:使用复制方法进行深度复制:
带有反射的0.490 s 浅复制:
使用复制方法进行5.499 s 浅复制:0.144 s


Jor*_*dão 1

您可以尝试使用AutoMapper

Mapper.CreateMap<MyEntity, MyEntity>();

...

var copy3 = Mapper.Map<MyEntity, MyEntity>(original);
Run Code Online (Sandbox Code Playgroud)