提问人:chiccodoro 提问时间:11/12/2014 最后编辑:Communitychiccodoro 更新时间:11/12/2014 访问量:743
闭包会破坏序列化吗
Do closures break serialization
问:
今天,当 IIS 尝试将会话存储在 ASP.NET State Service 中时,我遇到了一个引用某个匿名内部类,指出它是不可序列化的:SerializationException
+<>c__DisplayClass10
程序集“Xyz,Version=1.2.5429.24450,Culture=neutral,PublicKeyToken=null”中的类型“Xyz.GeneralUnderstandingTests+ASerializableType+<>c__DisplayClass10”未标记为可序列化。
我在代码中查找了 lambda,并找到了不少,但其中大多数都不是新的,并且在序列化方面从未出现过任何问题。但后来我注意到我内置了一个新的 lambda 表达式,它“碰巧”构建了一个闭包。
在搜索 Stackoverflow 时,我发现了一些 Q&A 显示闭包不能用其他语言(例如 PHP *)序列化,但我没有设法找到 C# 的此类语句。但是,我已经能够构建一个非常简单的示例,该示例似乎可以确认闭包不可序列化,而“正常”函数是可序列化的closure serialization
[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
你能确认我的结论是正确的吗?
=> 有没有办法规避这个问题?
=> 这可能取决于所用编译器的内部结构吗?因为是编译器将 lambda/closure 表达式转换为匿名内部类。
*) 友情链接:
答: 暂无答案
评论