Dan*_*iel 6 inheritance f# compiler-errors protected f#-3.0
F#3.0为呼叫base和protected成员添加了更严格的检查.我有类似C#中的以下抽象类,它有protected static派生类使用的辅助方法.
public abstract class Processor {
public abstract void Process();
protected static void Helper(object arg) { }
}
Run Code Online (Sandbox Code Playgroud)
在F#中,其中一个辅助方法作为第一类函数传递:
type DerivedProcessor() =
inherit Processor()
let init f =
f ()
override x.Process() =
init Processor.Helper
Run Code Online (Sandbox Code Playgroud)
它在2.0中没有投诉编译,但在3.0中产生错误:
被调用的受保护成员或正在使用"基础".这只能在成员的直接实现中使用,因为它们可以逃避它们的对象范围.
好的,它很容易遵守,只需将调用包装在另一个静态成员中
static member private HelperWrapper(arg) = Processor.Helper(arg)
Run Code Online (Sandbox Code Playgroud)
并通过那个intead.但为什么?
C#对于同样的模式没有问题.
public class HappyToCompile : Processor {
private void Init(Action<object> f) {
f(null);
}
public override void Process() {
Init(Helper);
}
}
Run Code Online (Sandbox Code Playgroud)
问题:
使用我的心灵语言设计技巧,我猜F#2.0正在生成无法验证的代码.见这对埃里克利珀的博客文章在C#中的一个相关问题的解释(因为C#4,IIRC已经固定).
简而言之,当您创建一个F#函数时,您实际上正在创建一个派生自的新类FSharpFunc<_,_>,并且从该类中调用受保护的方法是无效的,因为它不在继承链中.
当然,编译器可以只执行您正在执行的操作(创建一个私有方法并使用它),而不是禁止这些调用,但可能认为这些优点不会超过实现该改进的成本.
| 归档时间: |
|
| 查看次数: |
375 次 |
| 最近记录: |