一次声明静态和实例成员的惯用方法?
Idiomatic way to declare static and instance member at once?
当我用新函数扩展一个类型时,我通常希望它既可以点表示法也可以自由形式使用。根据情况,两者都可以更具可读性,前者有助于 IntelliSense,而后者有助于柯里化。
在 C#/VB.net 中,扩展方法执行此操作(尽管我不能像在 F# 中那样将函数限制为扩展静态 class 的静态方法)。我可以一次编写该函数,然后以两种方式调用它:
<Extension>
public function bounded(s as string, min as UShort, max as UShort) as string
if min > max then throw new ArgumentOutOfRangeException
if string.IsNullOrEmpty(s) then return new string(" ", min)
if s.Length < min then return s.PadRight(min, " ")
if s.Length > max then return s.Substring(0, max)
return s
end function
' usage
dim b1 = bounded("foo", 10, 15)
dim b2 = "foo".bounded(0, 2)
(这还不是很完美,因为我希望 bounded
成为 String
的静态方法,但 C#/VB.Net 不能那样做。指向F# 在这方面。)
另一方面,在 F# 中,我必须将函数与方法分开声明:
// works fine
[<AutoOpen>]
module Utilities =
type List<'T> with
member this.tryHead = if this.IsEmpty then None else Some this.Head
module List =
let tryHead (l : List<'T>) = l.tryHead
问题:是否有更优雅的方式同时声明这两个方法?
我尝试使用:
// doesn't quite work
type List<'T> with
member this.tryHead = if this.IsEmpty then None else Some this.Head
static member tryHead(l : List<'T>) = l.tryHead
至少可以让我跳过模块声明,但是当定义编译时,它并不完全有效 - someList.tryHead
没问题,但是 List.tryHead someList
导致 Property tryHead is not static
错误。
奖金问题:如您所见,静态成员定义需要类型注释。但是,没有其他类型可以访问刚刚定义的方法。那么,为什么不能推断出类型呢?
我不知道有什么方法可以在一行代码中声明两个 API,但是您可以通过使函数成为实现,然后定义函数的方法来摆脱类型注释:
[<AutoOpen>]
module Utilities =
module List =
let tryHead l = if List.isEmpty l then None else Some (List.head l)
type List<'a> with
member this.tryHead = List.tryHead this
当我用新函数扩展一个类型时,我通常希望它既可以点表示法也可以自由形式使用。根据情况,两者都可以更具可读性,前者有助于 IntelliSense,而后者有助于柯里化。
在 C#/VB.net 中,扩展方法执行此操作(尽管我不能像在 F# 中那样将函数限制为扩展静态 class 的静态方法)。我可以一次编写该函数,然后以两种方式调用它:
<Extension>
public function bounded(s as string, min as UShort, max as UShort) as string
if min > max then throw new ArgumentOutOfRangeException
if string.IsNullOrEmpty(s) then return new string(" ", min)
if s.Length < min then return s.PadRight(min, " ")
if s.Length > max then return s.Substring(0, max)
return s
end function
' usage
dim b1 = bounded("foo", 10, 15)
dim b2 = "foo".bounded(0, 2)
(这还不是很完美,因为我希望 bounded
成为 String
的静态方法,但 C#/VB.Net 不能那样做。指向F# 在这方面。)
另一方面,在 F# 中,我必须将函数与方法分开声明:
// works fine
[<AutoOpen>]
module Utilities =
type List<'T> with
member this.tryHead = if this.IsEmpty then None else Some this.Head
module List =
let tryHead (l : List<'T>) = l.tryHead
问题:是否有更优雅的方式同时声明这两个方法?
我尝试使用:
// doesn't quite work
type List<'T> with
member this.tryHead = if this.IsEmpty then None else Some this.Head
static member tryHead(l : List<'T>) = l.tryHead
至少可以让我跳过模块声明,但是当定义编译时,它并不完全有效 - someList.tryHead
没问题,但是 List.tryHead someList
导致 Property tryHead is not static
错误。
奖金问题:如您所见,静态成员定义需要类型注释。但是,没有其他类型可以访问刚刚定义的方法。那么,为什么不能推断出类型呢?
我不知道有什么方法可以在一行代码中声明两个 API,但是您可以通过使函数成为实现,然后定义函数的方法来摆脱类型注释:
[<AutoOpen>]
module Utilities =
module List =
let tryHead l = if List.isEmpty l then None else Some (List.head l)
type List<'a> with
member this.tryHead = List.tryHead this