.NET,C#:如何添加,作为ISerializable接口,一个自定义序列化属性 [英] .NET, C#: How to add a custom serialization attribute that acts as ISerializable interface

查看:734
本文介绍了.NET,C#:如何添加,作为ISerializable接口,一个自定义序列化属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做的分贝LINQ对象,其中包含的EntitySet和的EntityRef类的一些序列化。

I am doing some serialization of db linq objects, which contain EntitySet and EntityRef classes.

我发现了一个pretty的简单的方法来处理这​​些类,系列化只需使用ISerializable的妥善处理这种类型的(它们转换成名单序列化,并在反序列化解开吧)的成员。

I found a pretty easy way to deal with serialization of these classes, by simply using ISerializable to properly handle members of this type (converting them to lists for serialization, and undoing it on deserialization).

不过,这将是非常好的,如果我可以这样做:

However, it would be really nice if I could do:

[Serializable]
[SerializeLinqEntities]
partial class Person
{ ... }

相反的:

partial class Person : ISerializable
{
  public virtual void GetObjectData( SerializationInfo si, StreamingContext ctxt )
  {
    EntitySerializer.Serialize(this, typeof(Person), si, ctxt);
  }

  protected Person( SerializationInfo si, StreamingContext ctxt )
  {
    EntitySerializer.Deerialize(this, typeof(Person), si, ctxt);
  }
}

有没有办法做到这一点?我看了看,通过序列化类,并可能似乎无法找到任何方式来设置自定义序列化过滤程序(在那里我可以找我的自定义属性)。

Is there a way to do this? I looked through the serialization classes and couldn't seem to find any way to setup custom serialization filter routines (where I could look for my custom attribute).

谢谢!

推荐答案

是的,你可以通过实现做到这一点<一个href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializationsurrogate.aspx"相对=nofollow> ISerializationSurrogate 和 ISurrogateSelector 接口。

Yes, you can do this by implementing ISerializationSurrogate and ISurrogateSelector interfaces.

事情是这样的:

[AttributeUsage(AttributeTargets.Class)]
public class SerializeLinqEntities : Attribute
{
}

public class LinqEntitiesSurrogate : ISerializationSurrogate
{
    public void GetObjectData(
      object obj, SerializationInfo info, StreamingContext context)
    {
        EntitySerializer.Serialize(this, obj.GetType(), info, context);
    }

    public object SetObjectData(
      object obj, SerializationInfo info,
      StreamingContext context, ISurrogateSelector selector)
    {
        EntitySerializer.Deerialize(obj, obj.GetType(), info, context);
        return obj;
    }
}


/// <summary>
/// Returns LinqEntitySurrogate for all types marked SerializeLinqEntities
/// </summary>
public class NonSerializableSurrogateSelector : ISurrogateSelector
{
    public void ChainSelector(ISurrogateSelector selector)
    {
        throw new NotImplementedException();
    }

    public ISurrogateSelector GetNextSelector()
    {
        throw new NotImplementedException();
    }

    public ISerializationSurrogate GetSurrogate(
      Type type, StreamingContext context, out ISurrogateSelector selector)
    {
        if (!type.IsDefined(typeof(SerializeLinqEntities), false))
        {
            //type not marked SerializeLinqEntities
            selector = null;
            return null;
        }
        selector = this;
        return new LinqEntitiesSurrogate();
    }

}

[SerializeLinqEntities]
public class TestSurrogate
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Program
{
    static void Main(string[] str)
    {

        var ns1 = new TestSurrogate {Id = 47, Name = "TestName"};
        var formatter = new BinaryFormatter();
        formatter.SurrogateSelector = new NonSerializableSurrogateSelector();

        using (var ms = new MemoryStream())
        {
            formatter.Serialize(ms, ns1);
            ms.Position = 0;

            var ns2 = (TestSurrogate) formatter.Deserialize(ms);
            // Check serialization
            Debug.Assert(ns1.Id == ns2.Id);
            Debug.Assert(ns1.Name == ns2.Name);
        }
    }
}

这篇关于.NET,C#:如何添加,作为ISerializable接口,一个自定义序列化属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆