gpt4 book ai didi

c# - 复制一个模板对象以从中创建一个新的

转载 作者:行者123 更新时间:2023-11-30 22:01:57 24 4
gpt4 key购买 nike

我不知道如何解决我遇到的这类问题。

private Dictionary<int, Tire> m_vehicleTireSelected = new Dictionary<int, Tire>()
{
{0, new TireCasual()
{
Name = "Monster Tire",
Position = new Vector3(-0.94f, -1.09f)
}},
{1, new TireMonster()
{
Name = "Casual Tire",
Position = new Vector3(1.05f, -1.09f)
}}
};


public void ChangeTire(int tireIndex, int tireKey)
{
m_bus.ChangeTire(tireIndex, m_vehicleTireSelected[tireKey]);
}

所以我想在这里使用例如 Dictionary 来存储一些轮胎模板对象,然后用新的替换它们。这里的问题是,当我从字典中分配轮胎时,它仍然是同一个轮胎,因为它是一个引用类型变量,但最终我希望它是一个 COPY。有人可以帮助我,也许可以提出一个想法,我可以如何处理这种情况?我还应该提到,这是性能关键部分。

最佳答案

考虑到性能是您代码中的一个主要问题,我会避免使用自动深度克隆技术。相反,我建议使用 C# 中可用的最有效的内存克隆技术,Object.MemberwiseClone() ( see the MSDN page here )。此方法几乎是 C memcpy() API 的包装器,它直接复制引用的内存块并使整个过程快如闪电。这种技术的唯一警告是它创建了一个浅拷贝。也就是说,对象中的引用类型仍将指向同一个实例。要正确处理此问题,您需要做一些额外的工作。

public interface IDeepCloneable<T>
{
T DeepClone();
}

class Foo : IDeepCloneable<Foo>
{
public Foo DeepClone()
{
// The simplest usecase
return (Foo)this.MemberwiseClone();
}
}

class Bar : IDeepCloneable<Bar>
{
private Foo _foo;
private List<Foo> _lists;
private List<int> _valueTypedLists;

public Bar DeepClone()
{
var clone = (Bar)this.MemberwiseClone();

// This makes sure that deeper references are also cloned.
clone._foo = _foo.DeepClone();

// Though you still need to manually clone types that you do not own like
// lists but you can also turn this into an extension method if you want.
clone._lists = _lists.Select(f => f.DeepClone()).ToList();

// And you can simply call the ToList/ToArray method for lists/arrays
// of value type entities.
clone._valueTypedLists = _valueTypedLists.ToList();
return clone;
}
}

我做了一些基准测试来比较这种技术和上面评论中提出的二进制序列化器技术。以下是结果:

1 000 000 objects composed of 4 ints
Binary Serializer : 10.361799 seconds.
MemberwiseClone : 0.080879 seconds. (128x gain)

1 000 000 objects composed of 4 Lists<int> with 4 items (16 ints + 4 List)
Binary Serializer : 47.288164 seconds.
MemberwiseClone : 0.517383 seconds. (91x gain)

PS:您可能已经注意到我使用自己的界面而不是 System.ICloneable。这是因为内置接口(interface)是 .NET 2.0 时代的产物,当时泛型不可用。它还有一个重要警告,因为它没有正确说明其意图。基本上,没有办法知道 Clone 方法会产生什么。是浅拷贝还是深拷贝,甚至是同一类型?没有办法确定。这就是为什么我建议实现您自己的 IDeepCloneable 和 IShallowCloneable 接口(interface)。

关于c# - 复制一个模板对象以从中创建一个新的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27294398/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com