序列化在C#匿名委托 [英] Serializing anonymous delegates in C#

查看:150
本文介绍了序列化在C#匿名委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图确定什么问题,可以通过以下序列化代理,使匿名函数/委托/ lambda表达式的序列化造成的。

  //看到http://msdn.microsoft.com/msdnmag/issues/02/09/net/#S3
类NonSerializableSurrogate:ISerializationSurrogate
{
    公共无效GetObjectData使用(obj对象,SerializationInfo中的信息,的StreamingContext上下文)
    {
        的foreach(字段信息f由于obj.GetType()GetFields(BindingFlags.Instance |。BindingFlags.Public | BindingFlags.NonPublic可))
            info.AddValue(f.Name,f.GetValue(物镜));
    }

    公共对象SetObjectData(obj对象,SerializationInfo中的信息,的StreamingContext的背景下,
                                ISurrogateSelector选择)
    {
        的foreach(字段信息f由于obj.GetType()GetFields(BindingFlags.Instance |。BindingFlags.Public | BindingFlags.NonPublic可))
            f.SetValue(物镜,info.GetValue(f.Name,f.FieldType));
        返回OBJ;
    }
}
 

清单1 改编自计数演示

主要的问题我能想到的,可能是一个问题是匿名类是一个内部编译器细节和它的结构是不能保证留修订.NET框架之间不变。我敢肯定,这是根据我的研究,类似的问题,迭代器的情况。

背景

我调查的匿名函数序列化。我期待这不是工作,但发现它确实对一些案件。只要拉姆达没有*不和放大器;强制编译器生成一个匿名类一切工作正常。

如果编译器需要生成的类来实现匿名函数A SerializationException异常。这是因为编译器生成类没有标记为可序列化。

示例

 命名实例
{
    [可序列化]
    类其他
    {
        公共int值;
    }

    [可序列化]
    类节目
    {
        静态无效的主要(字串[] args)
        {
            MemoryStream的M =新的MemoryStream();
            的BinaryFormatter F =新的BinaryFormatter();

            //例1
            FUNC< INT>成功=()=> 5;
            f.Serialize(男,成功);

            //例2
            其他O =新的其他();
            FUNC< INT>失败=()=> o.Value;
            f.Serialize(男,失败); //抛出SerializationException  - 类型Example.Program + LT;> c__DisplayClass3汇编例如,版本= 1.0.0.0,文化=中性公钥=空'未标记为可序列化。
        }
    }
 

清单2

这是类似于试图序列化问题的的迭代器的,我已经找到了previous搜索以下code(请参阅[countingdemo])使用code从清单1 和ISurrogateSelector我能够成功序列化和反序列化的第二个失败的例子。

目标

我有一个是通过Web服务公开制度。该系统具有复杂但小国(很多对象,而不是很多的属性每个对象)。状态保存在ASP.NET缓存,但也被序列化到SQL中的BLOB的情况下缓存过期。有些对象需要在达到一定条件,以执行任意的事件。因此,他们有属性接受行动/函数对象。人为的例子:

 类命令
    {
        公共命令(动作动作,Func键<布尔>条件);
    }
 

别的地方

 无效DoSomethingWithThing(事嘛)
    {
        状态= Store.GetCurrentState();

        指令CMD =新的命令(()=> thing.Foo(),()=> thing.IsReady())
        state.Add(CMD);

        Store.Save(州);
    }
 

解决方案

你看到这篇文章,我写了一个后续的CountingDemo:的 http://dotnet.agilekiwi.com/blog/2007/12/update-on-persistent-iterators.html ?不幸的是,微软已证实,他们可能会改变编译器的信息(一天),的方式,有可能会产生问题。 (如F /当你更新到新的编译器,你将无法deserialise保存在旧的(当前)编译器的东西。)

I am trying to determine what issues could be caused by using the following serialization surrogate to enable serialization of anonymous functions/delegate/lambdas.

// see http://msdn.microsoft.com/msdnmag/issues/02/09/net/#S3
class NonSerializableSurrogate : ISerializationSurrogate
{
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
    {
        foreach (FieldInfo f in obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            info.AddValue(f.Name, f.GetValue(obj));
    }

    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context,
                                ISurrogateSelector selector)
    {
        foreach (FieldInfo f in obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            f.SetValue(obj, info.GetValue(f.Name, f.FieldType));
        return obj;
    }
}

Listing 1 adapted from Counting Demo

The main issue I can think of that might be a problem is that the anonymous class is an internal compiler detail and it's structure is not guaranteed to remain constant between revisions to the .NET Framework. I'm fairly certain this is the case based on my research into the similar problem with iterators.

Background

I am investigating the serialization of anonymous functions. I was expecting this not to work, but found it did for some cases. As long as the lambda did *not& force the compiler to generate an anonymous class everything works fine.

A SerializationException is thrown if the compiler requires a generated class to implement the anonymous function. This is because the compiler generated class is not marked as serializable.

Example

namespace Example
{
    [Serializable]
    class Other
    {
        public int Value;
    }

    [Serializable]
    class Program
    {
        static void Main(string[] args)
        {
            MemoryStream m = new MemoryStream();
            BinaryFormatter f = new BinaryFormatter();

            // Example 1
            Func<int> succeeds = () => 5;
            f.Serialize(m, succeeds);

            // Example 2
            Other o = new Other();
            Func<int> fails = () => o.Value;
            f.Serialize(m, fails); // throws SerializationException - Type 'Example.Program+<>c__DisplayClass3' in Assembly 'Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
        }
    }

Listing 2

This is similar to the issue of trying to serialize iterators and I had found the following code in a previous search (see [countingdemo]) Using the code from Listing 1 and an ISurrogateSelector I was able to successfully serialize and deserialize the second failing example.

Objective

I have a system that is exposed via a web service. The system has a complex but small state (many objects, not a lot of properties per object). The state is saved in the ASP.NET Cache, but is also serialized to a BLOB in SQL in case of cache expiration. Some objects need to execute arbitrary "events" upon reaching some condition. Hence they have properties accepting Action/Func objects. Contrived example:

    class Command
    {
        public Command(Action action, Func<bool> condition);
    }

Somewhere else

    void DoSomethingWithThing(Thing thing)
    {
        state = Store.GetCurrentState();

        Command cmd = new Command(() => thing.Foo(), () => thing.IsReady())
        state.Add(cmd);

        Store.Save(state);
    }

解决方案

Did you see this post that I wrote as a followup to the CountingDemo: http://dotnet.agilekiwi.com/blog/2007/12/update-on-persistent-iterators.html ? Unfortunately, Microsoft have confirmed that they probably will change the compiler details (one day), in a way that is likely to cause problems. (e.g. f/when you update to the new compiler, you won't be able to deserialise the stuff you saved under the old (current) compiler.)

这篇关于序列化在C#匿名委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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