C#中的委托与F#中作为一级值的函数之间有什么区别?
更具体地说,代表具有哪些作为F#中的一级值所没有的特征(如果有的话);作为一级值的函数有哪些C#中的委托所没有的特性(如果有的话?委托和F#“一级函数值”是完全不同的 委托是CLR的一种机制,是围绕函数指针+对象对的类型安全包装(例如方法,C#中的委托与F#中作为一级值的函数之间有什么区别?,c#,f#,delegates,first-class-functions,C#,F#,Delegates,First Class Functions,更具体地说,代表具有哪些作为F#中的一级值所没有的特征(如果有的话);作为一级值的函数有哪些C#中的委托所没有的特性(如果有的话?委托和F#“一级函数值”是完全不同的 委托是CLR的一种机制,是围绕函数指针+对象对的类型安全包装(例如方法,this-指针与方法地址一起捕获) 另一方面,F#函数值是一个抽象类的实现FSharpFunc(在F#正式发布之前,它曾被称为FastFunc)。调用通过普通的虚拟方法进行,这比委托调用快得多。 这就是F#团队最初没有使用代理的原因 那么,如果您可以通过抽象类
this
-指针与方法地址一起捕获)
另一方面,F#函数值是一个抽象类的实现FSharpFunc
(在F#正式发布之前,它曾被称为FastFunc
)。调用通过普通的虚拟方法进行,这比委托调用快得多。
这就是F#团队最初没有使用代理的原因
那么,如果您可以通过抽象类/虚拟方法将函数“实现”为第一类值,那么Microsoft为什么要添加委托呢
- 在.NET 1.0/1.1中没有替代方法,没有泛型,因此必须为要使用的每个函数签名定义一个新的委托类型(=“函数类型”)李>
- (不,仅仅使用Java中的接口并不重要。:-P)
Func
和Action
- 向后兼容性
- 多播代理可以将代理链接在一起以形成新代理。此机制用于在VB.NET和C#中实现事件。在幕后,事件实际上只是一个委托字段。使用
语法,您可以将事件处理程序委托添加到事件字段中的委托链中+=
FSharpFunc
是的,一个:FSharpFunc
的每个实现,包括lambda表达式*,都是一个新类。NET中的类在已编译程序集的元数据中进行编码。另一方面,委托不需要额外的元数据。委托类型没有,但实例化这些委托类型在元数据方面是免费的
但是等等,C#lambda表达式/匿名方法不是也作为隐藏类实现吗?
是的,C#lambdas两全其美^ ^我只想补充一点,SealedSun的这句话是不正确的: 调用通过普通的 虚拟方法,这要快得多 而不是委托调用。这就是问题所在 F队没有使用的原因 首先是代表 F#函数的速度并不比委托调用快,也许在.NET1.0中就是这样,但现在委托调用和调用虚拟方法的速度差不多 此外,与调用委托相比,调用编译器不能静态绑定的F#函数的速度非常慢
open System
open System.Diagnostics
let time name f =
let sw = new Stopwatch()
sw.Start()
f()
sw.Stop()
printfn "%s: %dms" name sw.ElapsedMilliseconds
time "delegate call" (
fun () ->
let f =
new Func<int, int, int>(
fun i1 i2 ->
let y = i1 + i2
let x = y + i1
let z = x + y + i2
z + x + y + i1
)
let mutable r = 0
for i = 0 to 10000000 do
r <- f.Invoke(i, i)
)
let f i1 i2 =
let y = i1 + i2
let x = y + i1
let z = x + y + i2
z + x + y + i1
time "fsharp func (static bound)" (
fun () ->
let mutable r = 0
for i = 0 to 10000000 do
r <- f i i
)
let make f =
let mutable r = 0
for i = 0 to 10000000 do
r <- f i i
time "fsharp func (dynamic bound)" (
fun () -> make f
)
Console.ReadLine() |> ignore
@delnan,你不知道为什么你认为代表们被拴在C#上;Anders等人从一开始就将其纳入语言设计中。事实上,他在C#之前就已经在J++中包含了它们。至于代理是一个丑陋的实现,这是主观的,因此没有信息。如需参考,请参阅“C#lambdas双管齐下”:用一种多么悲观的方式来表达。。。但我明白你的意思;)我是否可以从你的回答中推断出,在F#中作为一级值发挥作用?与代理相比,唯一的优势是速度?函数中是否没有任何一类值会在我编写程序的方式中引入范式转换?在C#3.0中,这一点非常接近。在2.0中,委托编写起来非常麻烦(语法非常繁重),以至于您很少使用它们。F#型推理也有帮助。也就是说,我想说的是“语法糖的优势”导致了范式转换。请参阅,作为这方面的证据。@SealedSun:在以通用方式支持适当的高级函数操作(组合等)之前,不能真正调用C#FP语言。虽然我很喜欢模式匹配和简单的不变性,但严格来说,它们并不是FP的关键。@pblasucci函数组合、const和flip只是库函数。它们是.NET4.0的一部分,以FSharp运行时库的形式出现。但真正缺少的是自动咖喱和partial.application的良好语法。我相信你是对的,有一次我链接到了一个采访.Net团队的人,在那里讨论了这一点(虚拟vs委托)。然而,这并不完全是我的问题所在,编程语言似乎在激增,而F#和“功能”编程是当今的热门词汇。我想问的是,选择函数作为第一类价值观是否是一种哲学上的转变,值得研究,或者主要是以更客观的方式进行宣传(或营销)(这样我的问题就不会结束了)。
delegate call: 65ms
fsharp func (staticly linked): 4ms
fsharp func (dynamic invoke): 356ms