Reputation: 1367
I have a class in C# which looks like this:
class A {
protected SomeClass Field;
}
class B: A {}
and following code in F#:
type C() =
inherit B()
member this.SomeMethod() =
let magic() = base.Field.SomeMoreMagic(someParam) //this.Field also fails
...
in which I want to access the protected field Field
. I know that I could access protected fields from class B by simple type base.something
(which is also answered here) but when I type base.Field
to access protected field from class A I get an error that struct or class field is not accessible from this code location
, because Field
is declared in class A(?).
My question is, is there some possibility to access it?
Upvotes: 1
Views: 231
Reputation: 13577
The reason why your stub workaround works is because you're trying to access the protected field within the body of a let-bound function d
. Such functions are moved outside of the context they're defined in and compiled into subtypes of FSharpFunc
type. That is, you get something like this in the compiled F# code (simplified picture):
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);
}
}
Which means that the block of code where you tried to access the protected field is no longer part of class C
, and protected
modifier prevents access there.
Whereas if you bind the value outside of d
, you get something like this:
public class C : B
{
public int SomeMethod()
{
SomeClass stub = this.Field;
FSharpFunc<Unit, int> d = new d@11(stub);
return d.Invoke(null);
}
}
and no protected access happens outside class C
anymore.
Upvotes: 2
Reputation: 1367
I found a resolution to my problem. Code like this is incorrect:
type C() =
inherit B()
member this.SomeMethod() =
let d() = base.Field.SomeMagic(someParameter) //this.Field also fails
d()
but code like this works correctly:
type C() =
inherit B()
member this.SomeMethod() =
let stub = this.Field
let d() = stub.SomeMagic(someParameter)
d()
Upvotes: 2