我有一个类和一个如此定义的记录:
namespace Foo
type internal MyRecord =
{
aValue1 : int
aValue2 : int
}
static member (+) (left : MyRecord, right : MyRecord) : MyRecord =
{aValue1 = left.aValue1 + right.aValue1; aValue2 = left.aValue2 + right.aValue2;}
type internal Bar() =
member this.Baz() =
let myRecord1 = {aValue1 = 2; aValue2 = 3;}
let myRecord2 = {aValue1 = 7; aValue2 = 5;}
let sum = myRecord1 + myRecord2 //Does not compile
0
Run Code Online (Sandbox Code Playgroud)
这无法编译:
成员或对象构造函数"op_Addition"不是公共的.只能在声明类型中访问私有成员.受保护的成员只能从扩展类型访问,并且无法从内部lambda表达式访问.
两种类型都是内部的.如果我明确地将+
运算符设置为public,那么这也无济于事:
static member public (+) (left : MyRecord, right : MyRecord) : MyRecord
Run Code Online (Sandbox Code Playgroud)
什么做的工作才刚刚放弃者使用的操作和使用静态方法:
namespace Foo
type internal MyRecord =
{
aValue1 : int
aValue2 : int
}
static member Add (left : MyRecord, right : MyRecord) : MyRecord =
{aValue1 = left.aValue1 + right.aValue1; aValue2 = left.aValue2 + right.aValue2;}
type internal Bar() =
member this.Baz() =
let myRecord1 = {aValue1 = 2; aValue2 = 3;}
let myRecord2 = {aValue1 = 7; aValue2 = 5;}
let sum = MyRecord.Add(myRecord1, myRecord2) //Does compile
0
Run Code Online (Sandbox Code Playgroud)
在使用命名成员工作时,为什么F#编译器在这种情况下使用运算符很困难?
将两种类型更改为公共而不是内部也可以解决编译错误.
我正在使用Visual Studio 2012和F#3.0,目标是.NET Framework 3.5.
我不知道为什么F#编译器有这个问题.这可能与F#中操作符的处理方式有关,也可能与处理可访问性的方式有关.你必须记住,用这种语言并不是一切都是它看起来的样子.通过做出一些牺牲已经实现了一些"面向对象"的特征.也许这就是其中之一.
但.我知道如何解决这个:).不要在实现文件中将类型设置为内部.而是使用签名.像这样定义文件Foo.fsi:
namespace Foo
type internal MyRecord =
{
aValue1 : int
aValue2 : int
}
[<Class>]
type Bar =
member Baz : unit -> int
Run Code Online (Sandbox Code Playgroud)
和Foo.fs这样:
namespace Foo
type MyRecord =
{
aValue1 : int
aValue2 : int
}
static member (+) (left : MyRecord, right : MyRecord) : MyRecord =
{aValue1 = left.aValue1 + right.aValue1; aValue2 = left.aValue2 + right.aValue2;}
type Bar() =
member this.Baz() =
let myRecord1 = {aValue1 = 2; aValue2 = 3;}
let myRecord2 = {aValue1 = 7; aValue2 = 5;}
let sum = myRecord1 + myRecord2 //Compiles
0
Run Code Online (Sandbox Code Playgroud)
这使您的代码有效且MyRecord
内部.