闭包会破坏序列化

时间:2014-11-12 12:50:43

标签: c# serialization lambda closures

今天我遇到一个SerializationException引用了一些匿名内部类+<>c__DisplayClass10,说明它不可序列化,当IIS试图将会话存储在ASP.NET状态服务中时:

  

键入&#39; Xyz.GeneralUnderstandingTests + ASerializableType +&lt;&gt; c__DisplayClass10&#39;在Assembly&#39; Xyz,Version = 1.2.5429.24450,Culture = neutral,PublicKeyToken = null&#39;未标记为可序列化。

我在代码中查找了lambdas并发现了很多,但是大多数都不是新的,并且在序列化方面从来没有任何问题。但后来我发现我已经内置了一个新的lambda表达式&#34;发生了#34;建立一个封闭。

搜索Stackoverflow closure serialization我发现了一些Q&amp; As,这表明闭包不能用其他语言(如PHP *)序列化,但我没有设法为C#找到这样的声明。然而,我已经能够构建一个非常简单的例子,似乎证实了闭包不是可序列化的,而#34; normal&#34;功能是

[TestFixture]
public class GeneralUnderstandingTests
{
    [Serializable]
    private class ASerializableType
    {
        private readonly Func<int> thisIsAClosure;
        private readonly Func<int> thisIsNotAClosure;

        public ASerializableType()
        {
            const int SomeConst = 12345;
            thisIsNotAClosure = () => SomeConst; // succeeds to serialize

            var someVariable = 12345;
            thisIsAClosure = () => someVariable; // fails to serialize
        }
    }

    [Test]
    public void ASerializableType_CanBeSerialized()
    {
        var sessionStateItemCollection = new 
            System.Web.SessionState.SessionStateItemCollection();
        sessionStateItemCollection["sut"] = new ASerializableType();
        sessionStateItemCollection.Serialize(new BinaryWriter(new MemoryStream()));
    }
}

此测试失败,但只要注释掉行thisIsAClosure = ...,就会变为绿色。然而,行thisIsNotAClosure = ...不会引起任何问题,因为SomeConst不是变量而是常量,也就是说,它不构建闭包但是由编译器内联。

你能否证实我的结论是正确的?

=&GT;有没有办法绕过这个问题?

=&GT;难道这取决于所用编译器的内部结构吗?因为编译器将lambda / closure表达式转换为匿名内部类。

*)链接:

0 个答案:

没有答案