我在扩展类型(在F#中)有以下代码,它调用它继承的类的受保护方法(在C#中),但我得到了异常(见下文).这有解决方法吗?
let getPagereference id =
this.ConstructPageReference(id)
Run Code Online (Sandbox Code Playgroud)
无法访问成员或对象构造函数"ConstructPageReference".只能在声明类型中访问私有成员.受保护的成员只能从扩展类型访问,并且无法从内部lambda表达式访问.
更新:
我试过跟随但得到相同的结果
let getPagereference id =
base.ConstructPageReference(id)
Run Code Online (Sandbox Code Playgroud)
更新2(解决方案):
这是代码:
type MyNewType() =
inherit SomeAbstractType()
let getPagereference id =
base.ConstructPageReference(id)
override this.SomeMethod()=
let id = 0
let pr = getPagereference id
Run Code Online (Sandbox Code Playgroud)
这应该是这样的:
type MyNewType() =
inherit SomeAbstractType()
member this.ConstructPageReference(id) =
base.ConstructPageReference(id)
override this.SomeMethod()=
let id = 0
let pr = this.ConstructPageReference(id)
Run Code Online (Sandbox Code Playgroud) 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#中实现友元函数和朋友类(如c ++)?
更新:由于f#中没有友元函数/类,而朋友甚至不是未来扩展的保留关键字,我想知道F#中的朋友机制是否有任何问题导致开发人员决定不实现它? (例如在"受保护的"访问修饰符中).
建议1:Brian,签名文件 - 我认为这件事情不正常.如果你有一个闭包(例如A中的lambda表达式,它是一个与A的实例不同的对象)来评估BX,它将无法工作
建议2:Massif(+ Mitya0),InternalsVisibleTo - 我不清楚,你是在第二课中写这个还是将课程暴露给整个集会?
我有这个基类创建一个新的SQL Server连接并在C#中做一些实用工具方法,我想在F#中继承.目前我无法从F#访问C#类中的受保护字段,尽管这可以在C#中使用.
C#抽象类
public abstract class SQL
{
protected readonly SqlConnectionStringBuilder bld;
protected readonly SqlCommand cmd;
protected readonly SqlConnection conn;
protected readonly string connstring;
protected string userid;
public SQL(string server, string db)
{
bld = new SqlConnectionStringBuilder();
bld.DataSource = server;
bld.InitialCatalog = db;
bld.IntegratedSecurity = true;
connstring = bld.ConnectionString;
conn = new SqlConnection(connstring);
cmd = new SqlCommand();
GetUserID();
//Other utility methods here
}
Run Code Online (Sandbox Code Playgroud)
要继承的F#代码
type Transfer ( server : string ) ( db : string ) =
inherit SQL(server, db) …Run Code Online (Sandbox Code Playgroud)