我在C#中有一个类,如下所示:
class A {
protected SomeClass Field;
}
class B: A {}
并在F#中使用以下代码:
type C() =
inherit B()
member this.SomeMethod() =
let magic() = base.Field.SomeMoreMagic(someParam) //this.Field also fails
...
我想访问受保护的字段Field
。我知道我可以通过简单类型base.something
(which is also answered here)访问B类中的受保护字段,但是当我输入base.Field
来访问类 A 中的受保护字段时得到struct or class field is not accessible from this code location
的错误,因为在类A(?)中声明了Field
。
我的问题是,是否有可能访问它?
答案 0 :(得分:2)
我找到了解决问题的方法。 像这样的代码不正确:
type C() =
inherit B()
member this.SomeMethod() =
let d() = base.Field.SomeMagic(someParameter) //this.Field also fails
d()
但是这样的代码可以正常工作:
type C() =
inherit B()
member this.SomeMethod() =
let stub = this.Field
let d() = stub.SomeMagic(someParameter)
d()
答案 1 :(得分:2)
您的存根解决方法之所以有效,是因为您尝试访问let-bound函数d
正文中的受保护字段。这些函数被移出它们定义的上下文之外并被编译成FSharpFunc
类型的子类型。也就是说,你在编译的F#代码(简化图片)中得到类似的东西:
internal class d@11 : FSharpFunc<Unit, int>
{
public C @this;
internal d@11(C @this)
{
this.@this = @this;
}
public override int Invoke(Unit unitVar0)
{
// this would be an attempt to access the protected field
// if the compiler allowed it.
return @this.Field.SomeMoreMagic();
}
}
public class C : B
{
public int SomeMethod()
{
FSharpFunc<Unit, int> d = new d@11(this);
return d.Invoke(null);
}
}
这意味着您尝试访问受保护字段的代码块不再属于类C
,而protected
修饰符会阻止访问。
如果你将值绑定在d
之外,你可以得到类似的结果:
public class C : B
{
public int SomeMethod()
{
SomeClass stub = this.Field;
FSharpFunc<Unit, int> d = new d@11(stub);
return d.Invoke(null);
}
}
并且不再在类C
之外发生受保护的访问。