I filled in the remaining expression types and greatly cleaned up the code for serializing LINQ expression trees. I think I got all the expression types correctly handled. Based on my current experiments, both simple and complex expression trees can so far be serialized without issue using the BinaryFormatter .
Some observations:
- My default implementation created a matching serializable expression type for each LINQ expression type. This made the implementation straight forward. I also learned a great deal about the structure of the expression trees. Whether I leverage the serialization code heavily or not in the future, this knowledge alone was worth it.
- Expression trees in serialized form are ridiculously too big. The culprit here is the default behavior of serialization with the BinaryFormatter. The BinaryFormatter writes out metadata describing all the types represented in the object graph. In this case, it has to provide the metadata for all of the expression types represented in the graph. The metadata for a simple 70-80 byte expression in C# source form comes out to be over 4KB in size. Yikes!
- Mouth, meet foot. My confidence was unfounded. The DataContractSerializer fails on the expression trees. The DataContractSerializer requires known types to be specified ahead of time. Unfortunately, some of the objects referenced by the expression trees rely on a type, System.RuntimeType. System.RuntimeType is marked internal and cannot be provided as part of the known types list.
Comments