如何在C#中使用System.Reflection对象的深层副本?使用System.Reflection对象的深层副本?
回答
一个简单的方法是使用JSON:
public static T DeepClone<T>(T source)
{
var serialized = JsonConvert.SerializeObject(source);
return JsonConvert.DeserializeObject<T>(serialized);
}
这确实反映了你。显然,它不适用于任何对非托管对象有句柄等任何事情。
(可以使用的NuGet来Newtonsoft.Json安装到你的项目。)
默认的Json不会连载私有字段。
可以解决这个问题,像这样:
public static T DeepClone<T>(T source)
{
var settings = new JsonSerializerSettings {ContractResolver = new MyContractResolver()};
var serialized = JsonConvert.SerializeObject(source, settings);
return JsonConvert.DeserializeObject<T>(serialized);
}
public class MyContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Select(p => base.CreateProperty(p, memberSerialization))
.Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Select(f => base.CreateProperty(f, memberSerialization)))
.ToList();
props.ForEach(p => { p.Writable = true; p.Readable = true; });
return props;
}
}
这里有一个完整的示例控制台应用程序,演示如何与私人领域的任意类可以被克隆。需要注意的是Json
尝试使用构造函数来设置字段和/或属性,如果构造函数的参数名称不匹配的字段或属性名称也将无法正常工作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace ConsoleApplication1
{
class Test
{
public Test(double y, string s, int x)
{
this.Y = y;
this.s = s;
this.X = x;
}
public int X;
public double Y { get; private set; }
public string Z
{
get
{
return s;
}
}
private string s;
}
class Program
{
static void Main()
{
var test = new Test(1.2345, "12345", 12345);
test.X = 12345;
var copy = DeepClone(test);
Console.WriteLine("X = " + copy.X);
Console.WriteLine("Y = " + copy.Y);
Console.WriteLine("Z = " + copy.Z);
}
public static T DeepClone<T>(T source)
{
var settings = new JsonSerializerSettings {ContractResolver = new MyContractResolver()};
var serialized = JsonConvert.SerializeObject(source, settings);
return JsonConvert.DeserializeObject<T>(serialized);
}
public class MyContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Select(p => base.CreateProperty(p, memberSerialization))
.Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Select(f => base.CreateProperty(f, memberSerialization)))
.ToList();
props.ForEach(p => { p.Writable = true; p.Readable = true; });
return props;
}
}
}
}
这不适用于任何对象。对象必须准备好序列化。 – Sinatr
@Sinatr它将适用于许多对象 - 如果您需要使用递归,那么该对象无论如何都必须是可序列化的。 –
@Sinatr JSON.NET是不是像DataContractJsonSerializer ... –
- 1. 对象图的JavaScript深层副本
- 2. 2d对象数组的深层副本
- 3. 派生python对象的深层副本
- 4. 片段的深层副本
- 5. NSMutableDictionary的深层副本
- 6. QML ListModel的深层副本
- 7. 使用深层副本实现递归
- 8. 作为全局对象的QScriptValue的深层副本
- 9. OpenCV cv深层副本::垫
- 10. 是否存在无法创建深层副本的对象?
- 11. 如何做NHibernate对象的深层副本?
- 12. 对象和数组的ECMAScript5深层副本
- 13. 重载=运算符时返回对象的深层副本
- 14. PHP数组引用的深层副本
- 15. 深层副本对象阵列属性与jQuery
- 16. SqlCommand.Clone()是否创建深层副本或浅层副本?
- 17. 如何使自定义对象的NSMutableArray属性的深层副本
- 18. Ruby中数组的深层副本
- 19. kxml节点的深层副本(java me)
- 20. 如何执行char *的深层副本?
- 21. 二叉树的深层副本
- 22. 教条记录的深层副本
- 23. 列表的深层副本<T>
- 24. 一个NSMutableDictionary的深层可变副本
- 25. 熊猫面板的深层副本?
- 26. 链接列表C++的深层副本
- 27. 不可变的深层副本
- 28. OrderedDict儿童的深层副本
- 29. C指针结构的深层副本
- 30. 可变的NSMutableDictionary深层副本
你为什么需要'反思?以及目前为止您尝试的内容 – Habib
属性/字段的递归。问题是要包含哪些内容,如何处理私有字段等等。因此,通过序列化现有序列化和反序列化新序列化,“克隆”对于专门准备好的序列化对象更容易。 – Sinatr