C# 在运行时将对象更改为可序列化的.NET
我想在运行时将对象更改为ISerializable。差不多C# 在运行时将对象更改为可序列化的.NET,c#,.net,serialization,C#,.net,Serialization,我想在运行时将对象更改为ISerializable。差不多 <!-- language: c# --> var nonSerializeObject = new NonSerialize(); ISerializable mySerializeObject = somethingforserializable.serialize(nonSerializeObject,TypeOfObject); var nonSerializeObject=新的NonSeriali
<!-- language: c# -->
var nonSerializeObject = new NonSerialize();
ISerializable mySerializeObject =
somethingforserializable.serialize(nonSerializeObject,TypeOfObject);
var nonSerializeObject=新的NonSerialize();
ISerializable mySerializeObject=
序列化(非序列化对象,类型化对象);
您可以创建一个可以序列化(转换为其他表示形式)对象的类,但无法在运行时向类添加接口(例如ISerializable
)
System.Xml.Serialization.XMLSerializer
类可以序列化类,而无需实现ISerializable
或[Serializable]
。最好是使用XML序列化或实现自己的序列化函数,这些函数使用反射来读取对象中的所有字段(请注意,反射只返回当前类型的私有字段,因此必须手动遍历类型层次结构)
您的起点将是
nonSerializeObject.GetType().GetFields()
方法。您不能添加从运行时派生的属性或接口/类。尽管这取决于序列化的方式,但它们可能根本不需要。很抱歉,您无法在运行时添加接口
能够放置一个对象来实现ISerializable并不意味着您可以正确地实现它
然而
通过反射,您可以获取类的所有字段并手动序列化它。也许可以把它放在一个泛型类中,作为可序列化的信封
大概是这样的:
public class SerializableEnvelope<T> : ISerializable
{
private T item;
public T Item
{
get { return item; }
}
public SerializableEnvelope(T _item)
{
item = _item;
}
public SerializableEnvelope(SerializationInfo info, StreamingContext context)
{
item = Activator.CreateInstance<T>();
FieldInfo[] fields = typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo field in fields)
field.SetValue(item, info.GetValue(field.Name, field.FieldType));
}
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
FieldInfo[] fields = typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo field in fields)
info.AddValue(field.Name, field.GetValue(item));
}
}
公共类SerializableEnvelope:ISerializable
{
私人物品;
公共交通项目
{
获取{return item;}
}
公共序列化信封(T_项)
{
项目=_项目;
}
公共SerializableEnvelope(SerializationInfo信息、StreamingContext上下文)
{
item=Activator.CreateInstance();
FieldInfo[]fields=typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach(字段中的字段信息字段)
field.SetValue(item,info.GetValue(field.Name,field.FieldType));
}
公共虚拟void GetObjectData(SerializationInfo信息、StreamingContext上下文)
{
FieldInfo[]fields=typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach(字段中的字段信息字段)
info.AddValue(field.Name,field.GetValue(item));
}
}
现在,我还没有尝试过它,而且它可能无法完全用于某些以不同寻常的方式存储数据的类。例如,我只获取私有字段,而某些类可能有公共字段。(不寻常,但可能发生)
如果嵌套对象也是不可序列化的,您也可能会遇到一些问题。但是,您可以检测到这一点并自动创建信封,并在反序列化时重建层次结构。这是一个非常奇怪的要求。。。你的目标到底是什么?是否有任何原因使相应的类型在编译时不可序列化???如果不使用BinaryFormatter,则不需要
serializable
这有一个重要缺陷-GetFields()只返回在调用它的类型上定义的私有字段。您必须沿着类型层次结构向上走才能获得其他字段。@Knaģis:True。。。符合事实的这就是为什么我总是将可序列化字段标记为受保护。所以,是的,不是那么容易,但有可能。