C# .NET可序列化实体
我需要使我的所有实体都可序列化。所以我想用一个带有备份和恢复方法的BaseEntity。但是在恢复中,我不能用保存的对象覆盖对象,因为C# .NET可序列化实体,c#,.net,serialization,entities,C#,.net,Serialization,Entities,我需要使我的所有实体都可序列化。所以我想用一个带有备份和恢复方法的BaseEntity。但是在恢复中,我不能用保存的对象覆盖对象,因为此是只读的 是否有任何解决方案或其他方法来获取可序列化实体 我的代码: internal class BaseEntity { private MemoryStream ms = new MemoryStream(); private BinaryFormatter bf = new BinaryFormatter(); public v
此
是只读的
是否有任何解决方案或其他方法来获取可序列化实体
我的代码:
internal class BaseEntity
{
private MemoryStream ms = new MemoryStream();
private BinaryFormatter bf = new BinaryFormatter();
public void Backup()
{
bf.Serialize(ms, this);
}
public void Restore()
{
this = (BaseEntity)bf.Deserialize(ms);
}
}
@jacklondon您将如何处理EntitySerializer方法
您可以使用StackService.Text模块为干净实体执行序列化过程。在ms方式中,您不需要任何属性(serializable/datacontract)
public class EntityFoo
{
public string Bar { get; set; }
public EntityFoo (string bar)
{
Bar = bar;
}
}
public class EntityDumper //and the EntitySerializer
{
public static string Dump<T> (T entity)
{
return new TypeSerializer<T> ().SerializeToString (entity);
}
public static T LoadBack<T> (string dump)
{
return new TypeSerializer<T> ().DeserializeFromString (dump);
}
}
public class dump_usage
{
public void start ()
{
string dump = EntityDumper.Dump (new EntityFoo ("Space"));
EntityFoo loaded = EntityDumper.LoadBack<EntityFoo> (dump);
Debug.Assert (loaded.Bar == "Space");
}
}
公共类EntityFoo
{
公共字符串条{get;set;}
公共实体foo(字符串栏)
{
巴=巴;
}
}
公共类EntityDumper//和EntitySerializer
{
公共静态字符串转储(T实体)
{
返回新的TypeSerializer().SerializeToString(实体);
}
公共静态T加载(字符串转储)
{
返回新的TypeSerializer().DeserializeFromString(转储);
}
}
公共类转储的使用
{
公共无效开始()
{
字符串转储=EntityDumper.dump(新的EntityFoo(“空格”);
EntityFoo loaded=EntityDumper.LoadBack(转储);
Assert(loaded.Bar==“Space”);
}
}
@jacklondon您将如何处理EntitySerializer方法
您可以使用StackService.Text模块为干净实体执行序列化过程。在ms方式中,您不需要任何属性(serializable/datacontract)
public class EntityFoo
{
public string Bar { get; set; }
public EntityFoo (string bar)
{
Bar = bar;
}
}
public class EntityDumper //and the EntitySerializer
{
public static string Dump<T> (T entity)
{
return new TypeSerializer<T> ().SerializeToString (entity);
}
public static T LoadBack<T> (string dump)
{
return new TypeSerializer<T> ().DeserializeFromString (dump);
}
}
public class dump_usage
{
public void start ()
{
string dump = EntityDumper.Dump (new EntityFoo ("Space"));
EntityFoo loaded = EntityDumper.LoadBack<EntityFoo> (dump);
Debug.Assert (loaded.Bar == "Space");
}
}
公共类EntityFoo
{
公共字符串条{get;set;}
公共实体foo(字符串栏)
{
巴=巴;
}
}
公共类EntityDumper//和EntitySerializer
{
公共静态字符串转储(T实体)
{
返回新的TypeSerializer().SerializeToString(实体);
}
公共静态T加载(字符串转储)
{
返回新的TypeSerializer().DeserializeFromString(转储);
}
}
公共类转储的使用
{
公共无效开始()
{
字符串转储=EntityDumper.dump(新的EntityFoo(“空格”);
EntityFoo loaded=EntityDumper.LoadBack(转储);
Assert(loaded.Bar==“Space”);
}
}
更常见的模式是不让对象自行序列化/反序列化;而是使用外部序列化程序:
var serializer = new DataContractJsonSerializer(typeof(YourClass));
var stream = ...;
YourClass yourObj = ...;
serializer.WriteObject(stream, yourObj);
var restoredObj = serializer.ReadObject(stream);
更常见的模式是不让对象负责序列化/反序列化它们自己;而是使用外部序列化程序:
var serializer = new DataContractJsonSerializer(typeof(YourClass));
var stream = ...;
YourClass yourObj = ...;
serializer.WriteObject(stream, yourObj);
var restoredObj = serializer.ReadObject(stream);
编辑:序列化工作的一种方式是使用System.Runtime.serialization.Formatters.Binary.BinaryFormatter(或其他IFormatter实现)。要序列化对象,请传递对象和流。要反序列化对象,需要传递一个流(位于序列化数据的开头),它返回序列化对象及其所有依赖项
public static class EntityBackupServices
{
public static MemoryStream Backup (BaseEntity entity)
{
var ms = new MemoryStream();
Serialize (ms, entity);
ms.Position = 0;
return ms;
}
public static void Serialize (Stream stream, BaseEntity entity)
{
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize (stream, entity);
}
public static BaseEntity Restore (Stream stream)
{
var binaryFormatter = new BinaryFormatter();
var entity = (BaseEntity) binaryFormatter.Deserialize (stream);
return entity;
}
}
格式化程序不做的一件事(尽管FormatterServices类使之成为可能)是修改现有对象。因此,您可能不希望有一个名为反序列化的实例方法。您无法真正做到这一点:new LionEntity()。反序列化()
,它将替换现有实例的字段
注意:你需要把所有的类型都放在上面。任何无法序列化的字段(因为它不是结构或未标记为[Serializable])都需要标记为
编辑:
我提到的方法是一种相当标准和公认的方法。如果你想冒险进入hackdom,你可以用我提到的方法反序列化对象,然后使用反射将现有对象上的每个字段设置为反序列化对象的值
public class BaseEntity
{
void Restore(Stream stream)
{
object deserialized = EntityBackupServices.RestoreDeserialize(stream);//As listed above
if (deserialized.GetType () != this.GetType ())
throw new Exception();
foreach (FieldInfo fi in GetType().GetFields())
{
fi.SetValue(this, fi.GetValue (deserialized));
}
}
}
编辑:序列化工作的一种方法是使用System.Runtime.serialization.Formatters.Binary.BinaryFormatter(或其他IFormatter实现)。要序列化对象,请传递对象和流。要反序列化对象,请传递流(位于序列化数据的开头),并返回序列化对象及其所有依赖项
public static class EntityBackupServices
{
public static MemoryStream Backup (BaseEntity entity)
{
var ms = new MemoryStream();
Serialize (ms, entity);
ms.Position = 0;
return ms;
}
public static void Serialize (Stream stream, BaseEntity entity)
{
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize (stream, entity);
}
public static BaseEntity Restore (Stream stream)
{
var binaryFormatter = new BinaryFormatter();
var entity = (BaseEntity) binaryFormatter.Deserialize (stream);
return entity;
}
}
格式化程序不做的一件事(尽管FormatterServices类使之成为可能)是修改现有对象。因此,您可能不希望有一个名为反序列化的实例方法。您不能真正做到这一点:new LionEntity()。反序列化()
,它将替换现有实例的字段
注意:您需要覆盖所有类型。任何无法序列化的字段(因为它不是结构或未标记为[Serializable])都需要标记为
编辑:
我提到的方法是一种相当标准和公认的方法。如果你想冒险进入hackdom,你可以用我提到的方法反序列化对象,然后使用反射将现有对象上的每个字段设置为反序列化对象的值
public class BaseEntity
{
void Restore(Stream stream)
{
object deserialized = EntityBackupServices.RestoreDeserialize(stream);//As listed above
if (deserialized.GetType () != this.GetType ())
throw new Exception();
foreach (FieldInfo fi in GetType().GetFields())
{
fi.SetValue(this, fi.GetValue (deserialized));
}
}
}
我不一定推荐这样做,但对于一个对象来说,有一种模式可以使用创建新实例的序列化来持久化和恢复其自身的状态:
public sealed class MyClass
{
private Data _data = new Data();
//Properties go here (access the public fields on _data)
public void Backup()
{
//Serialize Data
}
public void Restore()
{
//Deserialize Data and set new instance
}
private sealed class Data
{
//Public fields go here (they're private externally [because Data is private], but public to MyClass.)
}
}
请注意,这仅在序列化程序支持非公共类的情况下有效。最坏的情况是,必须将嵌套类设置为公共类,这很难看,但不会影响封装(因为实例是私有的).我不一定推荐这样做,但对于一个对象来说,有一种模式可以使用创建新实例的序列化来持久化和恢复其自身的状态:
public sealed class MyClass
{
private Data _data = new Data();
//Properties go here (access the public fields on _data)
public void Backup()
{
//Serialize Data
}
public void Restore()
{
//Deserialize Data and set new instance
}
private sealed class Data
{
//Public fields go here (they're private externally [because Data is private], but public to MyClass.)
}
}
请注意,这仅在序列化程序支持非公共类的情况下有效。最糟糕的情况是,您必须将嵌套类公开,这很难看,但不会影响封装(因为实例是私有的)。它不需要是静态的才有用吗?@jacklondon:是的,这可能是一个解决方案,但我更喜欢(如果可能的话)序列化必须包含在实体中。这样,从