Lambda、封闭变量、显示类、可序列化性和流行层
我已经为 Compact Framework 实现了一个流行层(包括类似 BinaryFormatter
的序列化器)。我希望能够在适当的情况下序列化编译器生成的类,这些类是由 lambda 和迭代器等产生的,这样如果(例如) lambda 及其封闭变量(即显示类实例)添加到可序列化对象上的事件,并且所有封闭变量都是可序列化的,则生成的对象图仍然是完全可序列化的。
如果这些类的实例只能通过与其序列化的二进制文件的完全相同的版本进行反序列化,那么这是可以接受的——流行层主要是为了在应用程序意外终止(电源故障)时提供持久性和设备重新启动是不同的可能性),并且序列化数据流预计不会向前或向后兼容,甚至不会在同一源代码的两个编译之间兼容 - 结果的所有内容都将发送到服务器无论如何,当我们下次与它交谈时,我们不会在断开连接时进行更新。
在这种有限的上下文中,我的格式化程序将这些编译器生成的类视为可序列化是否合理?我看到的唯一替代方案是在可序列化性受到关注的地方手动实现编译器支持的模式,其后果从过于冗长到几乎不可读。
I've implemented a prevalence layer for Compact Framework (including a BinaryFormatter
-like serializer). I'd like to be able to serialize the compiler-generated classes that result from such things as lambdas and iterators where appropriate, so that if (for example) a lambda and its closed-over variables (that is, the display class instance) is added to an event on a serializable object, and all the closed-over variables are serializable, then the resulting object graph is still fully serializable.
It's acceptable if instances of these classes can only be deserialized by the exact same build of the binaries that they were serialized from -- the prevalence layer is mostly to provide durability should the application be terminated unexpectedly (power failure and device reboot are distinct possibilities), and the serialized data stream is not expected to be either forward or backward compatible, or even for that matter compatible across two compiles of the same source code -- everything of consequence will be sent up to a server when we next talk to it anyway, and we're not going to update while disconnected.
Is it reasonable in this limited context for my formatter to treat these compiler-generated classes as if they were serializable? The only alternative I see is to hand-implement what areotherwise compiler-supported patterns everywhere serializability is a concern, with consequences ranging from the overly verbose to the nearly unreadable.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我明白你的意思,但根据我的经验,集中精力序列化数据是一个更好的主意,并通过回滚/前进到已知状态来处理持久性,也许使用类似本地 CQRS 队列,或存储“如何到达那里”的其他方式。
关于具体问题,在问题的严格范围内(仅在同一版本上工作等)我猜应该没问题,但这在很大程度上取决于是否有任何事情在这些变量中捕获的没有合理的序列化 - 即类似于 UI 元素(很容易被不可见的
this
意外捕获)之类的东西,不能被重建(操作系统句柄等)。如果它是孤立的数据(我的意思是:图表只是来自您自己的代码中的数据 - 没有非托管依赖项),那么我想它应该没问题。另一个问题是 CF 缺乏完整框架中可用的更强的反射,这可能会比常规框架上的情况更尴尬(
GetUninitializedObject
)。可能可行,但需要更多工作。I see what you are getting at, but in my experience it is a much better idea to concentrate on serializing data, and handle the durability by rolling back/forward to a known state, perhaps using something like a local CQRS queue, or some other way of storing "how you got there".
Re the specific question, within the tight scope of the question (only working on the same build etc) I guess that should be OK, but it depends a lot on whether anything that is captured in those variables has no sensible serialization - i.e. something like a UI element (easily accidentally captured with an invisible
this
) that cannot be reconstructed (os handles, etc). If it is isolated data (by which I mean: the graph is just data from within your own code - no unmanaged dependencies), then I guess it should be OK.The other issue is that CF lacks much of the stronger reflection available in the full framework, that might make this a bit more awkward than it might be on regular framework (
GetUninitializedObject
for example). Probably doable, but a bit more work.