las*_*sen 22 .net c# serialization serializable
我需要持久化一个没有标记serializable属性的对象.该对象来自第三方库,我无法更改.
我需要将它存储在一个持久的位置,例如文件系统,因此最佳解决方案是将对象序列化为文件,但由于它未标记为可序列化,因此这不是一个直接的解决方案.
它是一个非常复杂的对象,它还包含其他对象的集合.
你们有任何关于如何解决这个问题的意见吗?代码永远不会在生产环境中运行,因此我几乎可以使用任何解决方案和性能.
XmlSerializer 如果类型是公共等,则可能是首先尝试的有用的东西
如果失败了,protobuf-net的v2(正在进行中,您需要从源代码构建,但我可以提供帮助)适用于未归属的对象,因此非常适合您控制之外的类型 - 您只需告诉它要包含哪些内容(通过DSL).v2代码不完整,但它涵盖了大多数常见场景,包括集合等(不完整的工作主要是回调和枚举).
您可以编写一个递归方法,使用反射来运行对象图以保持对象...将其放回可能会困难得多.谁知道这些对象中是否有任何对象持有对非托管或系统资源的引用.如果我要做这个坚果的任何事情,我会选择.GetFields(...)该类型的方法.
另一个想法......
如果您只是为了加速开发,那么为什么不用自己的适配器类包装它们的clases.这将允许您使用自己的简化模拟类替换第三方库,以便以后更好地替换和重用.
生病了...这比我想的那样容易.(虽然这有效......请考虑包装第三方课程.)
public static class Tools
{
public static XElement AsXml(this object input)
{
return input.AsXml(string.Empty);
}
public static XElement AsXml(this object input, string name)
{
if (string.IsNullOrEmpty(name))
name = input.GetType().Name;
var xname = XmlConvert.EncodeName(name);
if (input == null)
return new XElement(xname);
if (input is string || input is int || input is float /* others */)
return new XElement(xname, input);
var type = input.GetType();
var fields = type.GetFields(BindingFlags.Instance |
BindingFlags.NonPublic)
.Union(type.GetFields(BindingFlags.Instance |
BindingFlags.Public));
var elems = fields.Select(f => f.GetValue(input)
.AsXml(f.Name));
return new XElement(xname, elems);
}
public static void ToObject(this XElement input, object result)
{
if (input == null || result == null)
throw new ArgumentNullException();
var type = result.GetType();
var fields = type.GetFields(BindingFlags.Instance |
BindingFlags.NonPublic)
.Union(type.GetFields(BindingFlags.Instance |
BindingFlags.Public));
var values = from elm in input.Elements()
let name = XmlConvert.DecodeName(elm.Name.LocalName)
join field in fields on name equals field.Name
let backType = field.FieldType
let val = elm.Value
let parsed = backType.AsValue(val, elm)
select new
{
field,
parsed
};
foreach (var item in values)
item.field.SetValue(result, item.parsed);
}
public static object AsValue(this Type backType,
string val,
XElement elm)
{
if (backType == typeof(string))
return (object)val;
if (backType == typeof(int))
return (object)int.Parse(val);
if (backType == typeof(float))
return (float)int.Parse(val);
object ret = FormatterServices.GetUninitializedObject(backType);
elm.ToObject(ret);
return ret;
}
}
public class Program
{
public static void Main(string[] args)
{
var obj = new { Matt = "hi", Other = new { ID = 1 } };
var other = new { Matt = "zzz", Other = new { ID = 5 } };
var ret = obj.AsXml();
ret.ToObject(other);
Console.WriteLine(obj); //{ Matt = hi, Other = { ID = 1 } }
Console.WriteLine(other); //{ Matt = hi, Other = { ID = 1 } }
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5560 次 |
| 最近记录: |