c# – 如何在WCF中使用DataContract / DataMember序列化Func(甚至是一般委托)类型字段

前端之家收集整理的这篇文章主要介绍了c# – 如何在WCF中使用DataContract / DataMember序列化Func(甚至是一般委托)类型字段前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试序列化一个Func< int,int>标有[DataMember]的字段,标有[DataContract]的类,其目标或Lambda表达式定义也是合同的一部分,或者甚至可以在类本身中.

我正在使用自定义DataContractResolver,当我取消标记Func字段时,它非常有效,但是当我标记它时,它不解析序列化所需的System.DelegateSerializationHolder类型.我试图将此类型添加到我的自定义DataContractResolver,但我无法在系统命名空间中找到它.

我可以在每个使用这个类的客户端类的[OnDeserialized]方法中重新定义它,但是每次我使用这个类时我都需要这样做,当然我想避免(客户端类也是DataContract的一部分) ).

此序列化暂时用于将应用程序的状态保存到磁盘,因此保存委托(甚至是我不感兴趣的事件)具有逻辑意义,因为它是对象图的所有部分.

那么如何序列化这个Func< int,int>使用WCF的DataContract?

解决方法

问题在于,无法使用默认的WCF序列化程序 – 委托序列化只能用于.NET.

解决方案是使用NetDataContractSerializer.在您的情况下,使用持久性上下文(或文件上下文):

var context = new StreamingContext(StreamingContextStates.Persistence);
var s = new System.Runtime.Serialization.NetDataContractSerializer();

var sb = new StringBuilder();

using (var writer = new XmlTextWriter(new StringWriter(sb)))
{      
    s.WriteObject(writer,new Test() { SomeFunc = (int i) => "Hi".Dump().Length });
}

sb.ToString().Dump();

[DataContract]
class Test
{
    [DataMember]
    public Func<int,int> SomeFunc;
}

请注意,序列化程序只会维护有关委托的信息 – 如果您只为代理使用编译时方法,这很好,但它不适用于动态编译的方法.被警告.

避免匿名函数也是一个好主意 – 虽然它们可以工作,但它们也可能在不同的构建之间发生变化,导致持久状态变为无效,可能带来灾难性的副作用.不要忘记,委托由方法名称(和返回类型,以及参数…)序列化 – 当名称更改时,持久委托将指向具有旧名称的新方法.即使使用非匿名方法,也要确保永远不要更改可能作为委托持久保存的方法 – 理想情况下,如果需要,使用原始方法签名提供向后兼容的行为.

如果您发现自己添加了对网络序列化的支持,只需添加更多StreamingContextStates即可.

猜你在找的C#相关文章