如果定义的类型要用于其他.NET 语言,应该把它们放在命名空间下,而不是模块中。这是因为模块在被编译成 C# 或其他.NET 语言时,被处理成类,在模块中定义的任何类型都成为这个类型内部的类。虽然对于 C# 来说,这并不是什么大问题,但是,如果用命名空间代替模块,C# 客户端代码看起来会更清晰。这是因为在 C# 中,只用using 语句导入(open)命名空间,而如果是在模块中的类型,在 C# 中使用时,就必须把模块名作为前缀。
让我们看一下这样的例子。下面的例子定义了类TheClass,它是在命名空间下;随类一起还提供几个函数,但不能直接放在命名空间下,因为,值不能在命名空间中定义。这里,定义了一个名字叫TheModule 模块,来管理函数值。
namespace Strangelights
open System.Collections.Generic
// this is a counterclass
type TheClass(i)
=
let mutable theField = i
member x.TheField
with get() =theField
// increments the counter
member x.Increment() =
theField <- theField
+ 1
// decrements the count
member x.Decrement() =
theField <- theField
- 1
// this is a module forworking with the TheClass
module TheModule = begin
// increments a list of TheClass
let incList (theClasses: List<TheClass>)
=
theClasses |> Seq.iter
(fun c ->c.Increment())
// decrements a list of TheClass
let decList (theClasses: List<TheClass>)
=
theClasses |> Seq.iter
(fun c ->c.Decrement())
end
在 C# 中使用TheClass 类,现在就很简单了,因为不必要加前缀,也可以很容易地访问到TheModule 中的相关函数:
// !!! C# Source !!!
usingSystem;
usingSystem.Collections.Generic;
usingStrangelights;
classProgram {
static
voidUseTheClass() {
// create a list of classes
List<TheClass> theClasses = newList<TheClass>() {
new TheClass(5),
new TheClass(6),
new TheClass(7)};
// increment the list
TheModule.incList(theClasses);
// write out each value in the list
foreach (TheClass c
in theClasses) {
Console.WriteLine(c.TheField);
}
}
static
voidMain(string[] args) {
UseTheClass();
}
}
在命名空间下定义类型