如何在 F# 中实现 ISerialized
假设您从这个存根开始:
[<Serializable>]
type Bounderizer =
val mutable _boundRect : Rectangle
new (boundRect : Rectangle) = { _boundRect = boundRect ; }
new () = { _boundRect = Rectangle(0, 0, 1, 1); }
new (info:SerializationInfo, context:StreamingContext) =
{ // to do
}
interface ISerializable with
member this.GetObjectData(info, context) =
if info = null then raise(ArgumentNullException("info"))
info.AddValue("BoundRect", this._boundRect)
// TODO - add BoundRect property
问题是规范说:“一般来说,如果类未密封,则应保护此构造函数。” F# 没有受保护的关键字 - 那么我该如何做到这一点?
约束(由于需要在 API 级别完美匹配现有的 C# 类):
- 必须实现 ISerialized
- 构造函数必须受到保护
编辑 - 有趣的额外信息 F# 规范表示,如果您覆盖受保护的函数,则生成的函数将受到保护。这是不正确的。如果您不指定可访问性,则无论如何,生成的覆盖都将是公开的(违反合同)。
Let's say you start off with this stub:
[<Serializable>]
type Bounderizer =
val mutable _boundRect : Rectangle
new (boundRect : Rectangle) = { _boundRect = boundRect ; }
new () = { _boundRect = Rectangle(0, 0, 1, 1); }
new (info:SerializationInfo, context:StreamingContext) =
{ // to do
}
interface ISerializable with
member this.GetObjectData(info, context) =
if info = null then raise(ArgumentNullException("info"))
info.AddValue("BoundRect", this._boundRect)
// TODO - add BoundRect property
The issue is that the spec says, "In general, this constructor should be protected if the class is not sealed." F# doesn't have a protected keyword - so how do I do this?
Constraints (due to a requirement to match perfectly existing C# classes at the API level):
- Must implement ISerializable
- Constructor must be protected
EDIT - interesting extra information
The F# spec says that if you override a protected function that the resulting function will be protected. This is incorrect. If you don't specify accessibility, the resulting override will be public no matter what (breaking the contract).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
目前无法按原样使用该语言来执行此操作。这是可以做到的,我有两种方法。
第一种方法是通过 ILDASM 运行输出程序集,将正则表达式转换为所需的方法声明,将所需方法中的“public”更改为“family”,然后将 ILASM 返回。呃wwwwww。
我正在研究的第二个方法是标记方法,
然后使用 CCI 编写一个过滤器来更改所有方法的可访问性都高于具有 ProtectedAttribute 的方法,然后删除该属性。这看起来比在文件上运行正则表达式更不体面,但我工作中的安全设置非常讨厌 CCI 项目源,所以我无法成功获取/解压缩/构建它。
编辑 - 这是我的解决方案 - 我尝试了 CCI,但它还没有准备好执行任务。我最终使用 Cecil 并最终得到以下代码:
中的属性
首先是 F# open System
,然后是以下应用程序是 Cecil 的客户端:
最后,用 MyProtectedAttribute 装饰您想要保护的方法并作为构建后步骤运行 C# 应用程序。
It is not possible to do this currently using the language as is. It is possible to do this and I have two ways.
The first is to run the output assembly through ILDASM, regex to the method declaration you want, change 'public' to 'family' in the method you want, then ILASM it back. Ewwwww.
The second, which I'm investigating, is to tag the methods with
then write a filter with CCI to change the accessibility on all methods than have the ProtectedAttribute and then remove the attribute. This seems less unseemly than running a regex over the file, but my security settings at work seriously hates the CCI project source, so I can't successfully fetch/decompress/built it.
EDIT - Here is my solution - I tried CCI, but it's not ready for the task. I ended up using Cecil and ended up with the following code:
First an attribute in F#
open System
then the following app which is a client of Cecil:
finally, decorate the methods you want to be protected with MyProtectedAttribute and run the C# app as a post-build step.
不幸的是,没有办法 - F# 没有受保护的成员。我们会在未来的版本中考虑这一点。
Unfortunately, there is no way - F# does not have protected members. We will consider this in future versions.
事实上 protected 修饰符不是强制执行,而是建议
所以这应该有效:
in fact protected modifier is not enforcement, but a recommendation
So this should work: