6

Today I faced a SerializationException that refered to some anonymous inner class +<>c__DisplayClass10 stating it was not serializable, when IIS tried to store the session in the ASP.NET State Service:

Type 'Xyz.GeneralUnderstandingTests+ASerializableType+<>c__DisplayClass10' in Assembly 'Xyz, Version=1.2.5429.24450, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

I looked for lambdas in my code and found quite a few, but most of them were not new and did never have any issues in serialization. But then I noticed that I had built in a new lambda expression that "happened" to build up a closure.

Searching Stackoverflow for closure serialization I found some Q&As that reveal that closures cannot be serialized in other languages such as PHP *) but I did not manage to find such a statement for C#. I have however been able to build a very simple example that seems to confirm that closures are not serializable whereas "normal" functions are

[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()));
    }
}

This test fails but goes green as soon as the line thisIsAClosure = ... is commented out. The line thisIsNotAClosure = ... however does not cause any issues as SomeConst is not a variable but a constant, that is, it does not build a closure but is inlined by the compiler.

Can you confirm that what I have concluded is correct?

=> Is there a way to circumvent this issue?

=> Could it be that this depends on the internals of the compiler used? Since it is the compiler that turns the lambda/closure expression into a anonymous inner class.

*) Links:

Community
  • 1
  • 1
chiccodoro
  • 14,407
  • 19
  • 87
  • 130
  • 2
    possible duplicate of [Serialize Composed Func?](http://stackoverflow.com/questions/3620882/serialize-composed-func) – Matias Cicero Nov 12 '14 at 12:59
  • 1
    @Mati - bingo! I'll help voting. But leave the question here because others might have a hard time like me finding that other question. Your comment is almost like an answer to the question therefore. – chiccodoro Nov 12 '14 at 13:02
  • No problem :P. You might also want to take a look at: [Serializing and Deserializing Expression Trees in C#](http://stackoverflow.com/questions/217961/serializing-and-deserializing-expression-trees-in-c-sharp) for a serialization workaround – Matias Cicero Nov 12 '14 at 13:04

0 Answers0