C# 在运行时将对象更改为可序列化的.NET

C# 在运行时将对象更改为可序列化的.NET,c#,.net,serialization,C#,.net,Serialization,我想在运行时将对象更改为ISerializable。差不多 <!-- language: c# --> var nonSerializeObject = new NonSerialize(); ISerializable mySerializeObject = somethingforserializable.serialize(nonSerializeObject,TypeOfObject); var nonSerializeObject=新的NonSeriali

我想在运行时将对象更改为ISerializable。差不多

<!-- 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。。。符合事实的这就是为什么我总是将可序列化字段标记为受保护。所以,是的,不是那么容易,但有可能。