简体   繁体   English

来自C#继承类的F#访问受保护字段

[英]F# access protected field from a C# inherited class

I have a class in C# which looks like this: 我在C#中有一个看起来像这样的类:

class A {
    protected SomeClass Field;
}

class B: A {}

and following code in F#: 以及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 . 我要在其中访问受保护的字段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(?). 我知道我可以通过简单类型base.something访问B类的受保护字段( 在此处也得到回答 ),但是当我键入base.Field访问A受保护字段时,我得到一个错误,指出struct or class field is not accessible from this code location ,因为Field在类A(?)中声明。 My question is, is there some possibility to access it? 我的问题是,是否有可能访问它?

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()

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 . 存根解决方案之所以起作用,是因为您试图访问让绑定函数d内的受保护字段。 Such functions are moved outside of the context they're defined in and compiled into subtypes of FSharpFunc type. 这些函数将移出它们定义的上下文之外,并编译为FSharpFunc类型的子类型。 That is, you get something like this in the compiled F# code (simplified picture): 也就是说,在已编译的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);
    }
}

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. 这意味着您尝试访问protected字段的代码块不再是C类的一部分,而且protected修饰符阻止了对该类的访问。

Whereas if you bind the value outside of d , you get something like this: 而如果将值绑定到d之外,则会得到以下内容:

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. 并且在C类之外不再发生受保护的访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM