我想做的事情如下:
MyObject myObj = GetMyObj(); // Create and fill a new object
MyObject newObj = myObj.Clone();
Run Code Online (Sandbox Code Playgroud)
然后更改未在原始对象中反映的新对象.
我不经常需要这个功能,所以当有必要的时候,我已经使用了创建一个新对象然后单独复制每个属性,但它总是让我觉得有更好或更优雅的处理方式情况.
如何克隆或深度复制对象,以便可以修改克隆对象而不会在原始对象中反映任何更改?
我在C#中有一个通用的对象列表,并希望克隆列表.列表中的项目是可复制的,但似乎没有选项可做list.Clone().
有一个简单的方法吗?
可能重复:
如何在.Net(特别是C#)中深层复制对象?
请看下面的代码(摘自C#书):
public class MyClass
{
public int val;
}
public struct myStruct
{
public int val;
}
public class Program
{
private static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = objectA;
objectA.val = 10;
objectB.val = 20;
myStruct structA = new myStruct();
myStruct structB = structA;
structA.val = 30;
structB.val = 40;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("structA.val = {0}", structA.val);
Console.WriteLine("structB.val = {0}", structB.val);
Console.ReadKey();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道它会产生下面的输出
objectA.val …Run Code Online (Sandbox Code Playgroud) 该RuntimeHelpers.GetHashCode(object)方法允许基于对象的身份生成哈希码.MSDN 声明:
RuntimeHelpers.GetHashCode方法始终非虚拟地调用Object.GetHashCode方法,即使对象的类型已重写Object.GetHashCode方法.
[MethodImpl(MethodImplOptions.InternalCall)]
[SecuritySafeCritical]
public static extern int GetHashCode(object o);
Run Code Online (Sandbox Code Playgroud)
但是,在Object.GetHashCode()使用Reflector(.NET 4.0)检查方法时,我们将看到以下代码:
public virtual int GetHashCode()
{
return RuntimeHelpers.GetHashCode(this);
}
Run Code Online (Sandbox Code Playgroud)
这让我相信MSDN文档是错误的,因为Object.GetHashCode从内部调用RuntimeHelpers.GetHashCode(object)会导致堆栈溢出.
那么它的实际行为是什么RuntimeHelpers.GetHashCode(object)以及它是如何工作的?它是如何计算哈希值的?
鉴于以下课程:
class A
{
public List<B> ListB;
// etc...
}
Run Code Online (Sandbox Code Playgroud)
哪个B是可以继承/包含其他类的另一个类.
鉴于这种情况:
A 是一个大类,包含许多引用类型B,[Serializable]因为我无法访问源代码B以下执行深度复制的方法不起作用:
ICloneable或MemberwiseClone作为类A包含许多引用类型A,因为类很大并且不断被添加到,并且包含B无法深度复制的类(如)B,没有可用的源代码)[Serializable]我怎样才能深造课A?
该备忘录模式本身似乎相当直截了当.我正在考虑实现与维基百科示例相同的功能,但在此之前我是否有C#的任何语言功能,以便更容易实现或使用?
引用这个问题的答案.
可以改写为:
private static BinaryFormatter formatter = new BinaryFormatter();
public static T DeepClone<T>(this T a)
{
using(MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, a);
stream.Position = 0;
return (T)formatter.Deserialize(stream);
}
}
Run Code Online (Sandbox Code Playgroud)
那么为每次调用避免构造(和GC)一个新的BinaryFormatter?
这个代码路径非常频繁,因为它涉及我们的缓存层,我想尽可能轻量级.
谢谢.
可能重复:
如何在C#中克隆通用列表?
List<MyObject> a1 = new List<MyObject>();
var new1 = a1;
Run Code Online (Sandbox Code Playgroud)
现在,如果我改变,a1那么new1也将改变.
所以我的问题是如何正确克隆a1?
我想检查Type是否是原始的,并使用以下代码:
return type.IsValueType && type.IsPrimitive;
Run Code Online (Sandbox Code Playgroud)
只要原语不可为空,这就可以正常工作.例如int ?,如何检查类型是否为可为空的原始类型?(仅供参考:type.IsPrimitive == false在int?)