2

是否有任何设计原因(比如他们放弃多继承的原因)?

或者它只是不够重要?

同样的问题适用于方法中的可选参数......这已经在vb.net的第一个版本中......所以肯定不会导致MS不允许可选参数的懒惰,可能是架构决定......而且似乎他们有改变主意,因为 C# 4 将包括那个..

有谁知道这个决定是什么以及他们为什么放弃它?

编辑:

也许你没有完全理解我。我最近正在研究一个计算程序(支持任何大小的数字,直到最后一位),其中某些方法每秒使用数百万次。

Add(1);假设我有一个名为 Add(int num) 的方法,并且该方法经常使用 1 作为参数(而且我的意思不是重载——编写一个名为 AddOne 的新方法,并将 Add 方法复制到其中,除了num我正在编写的不是使用1. 这对你来说可能看起来很奇怪,但实际上速度更快。

(尽管它很丑)

这让我想知道为什么 C# 不支持手动内联,这在这里非常有用。

谢谢。(以及你为什么投票给我:S)

编辑2:

我问自己是否要添加这个。我非常熟悉为此类项目选择 dot net 等平台的怪异(和缺点),但我认为 dot net 优化比您想象的更重要……尤其是 Any CPU 等功能。

4

7 回答 7

6

要回答您的部分问题,请参阅 Eric Gunnerson 的博客文章:为什么 C# 没有“内联”关键字?

引用他的帖子:

对于 C#,内联发生在 JIT 级别,而 JIT 通常会做出正确的决定。

编辑:我不确定延迟可选参数支持的原因,但是说他们“放弃”听起来好像他们应该根据我们对其他语言提供的期望来实现它。我想这在他们的优先级列表中并不高,而且他们有最后期限来为每个版本推出某些功能。直到现在,它的重要性可能还没有上升,特别是因为方法重载是一种可用的替代方案。同时,我们得到了泛型 (2.0),以及使 LINQ 成为可能的特性等 (3.0)。我对语言的进步感到满意;上述功能对我来说比早期获得对可选参数的支持更重要。

于 2009-10-25T18:29:37.677 回答
3

手动内联几乎没有用。JIT 编译器在本机代码编译期间内联方法,我认为几乎在所有情况下,JIT 编译器都比程序员更擅长猜测何时合适。

至于可选参数,我不知道为什么以前的版本没有。也就是说,我不喜欢它们出现在 C# 4 中,因为我认为它们有些有害,因为参数会被烘焙到使用程序集中,如果您更改 DLL 中的标准值并想要使用程序,则必须重新编译它装配以使用新的。

编辑:

有关内联的一些附加信息。尽管不能强制 JIT 编译器内联方法调用,但可以强制它不内联方法调用。为此,您使用 System.Runtime.CompilerServices.MethodImplAttribute,如下所示:

internal static class MyClass
{
    [System.Runtime.CompilerServices.MethodImplAttribute(MethodImplOptions.NoInlining)]
    private static void MyMethod()
    {
        //Powerful, magical code
    }

    //Other code
}
于 2009-10-25T18:25:25.190 回答
1

我有根据的猜测:早期版本的 C# 没有可选参数的原因是因为在 C++ 中使用它们的体验不好。从表面上看,它们看起来很直截了当,但也有一些令人讨厌的角落案例。我认为 Herb Sutter 的一本书更详细地描述了这一点。通常,它与覆盖virtual方法有关。 Maximilian在他的回答中提到了一个 .NET 极端案例。

你也可以通过手动编写多个重载来摆脱它们。这对类的作者来说可能不是很好,但是客户几乎不会注意到重载和可选参数之间的区别。

那么这些年来没有它们,为什么 C# 4.0 添加它们?1) 改进了与 VB.NET 的奇偶性,2) 更容易与 COM 互操作。

于 2009-10-25T18:35:16.070 回答
1

我最近正在研究一个计算程序(支持任何大小的数字,直到最后一位),其中某些方法每秒使用数百万次。

然后你选择了错误的语言。我假设您实际上分析了您的代码(对吗?)并且知道除了微优化之外没有什么可以帮助您。此外,您正在使用高性能的本机 bigint 库,而不是自己编写,对吗?

如果这是真的,请不要使用 .NET。如果您认为您可以在部分专业化方面获得速度,请使用 Haskell、C、Fortran 或任何其他可以自动完成或可以向您公开内联以手动完成的语言。

如果Add(1)对您来说真的很重要,那么堆分配也很重要。

但是,您应该真正查看分析器可以告诉您的内容...

于 2009-10-26T01:06:10.673 回答
0

C# 在 4.0 中添加了它们:http: //msdn.microsoft.com/en-us/library/dd264739 (VS.100).aspx

至于为什么他们没有从一开始就完成,这很可能是因为他们觉得方法重载提供了更多的灵活性。通过重载,您可以根据您正在采用的其他参数指定多个“默认值”。它也没有更多的语法。

于 2009-10-25T18:25:24.330 回答
0

即使在像 C++ 这样的语言中,内联也不能保证一定会发生。这是对编译器的提示。 编译器可以接受提示,也可以做自己的事情

C# 是从生成的汇编代码中删除的另一个步骤(通过 IL + JIT),因此更难保证某些内容会内联。此外,您还会遇到诸如 JIT 的 x86 + x64 实现在行为上不同的问题。

于 2009-10-25T18:32:44.347 回答
0

Java 也不包含inline关键字。更好的 Java JIT 甚至可以内联虚拟方法,使用诸如privatefinal之类的关键字也没有任何区别(过去曾经如此,但现在已成为古老的历史)。

于 2009-10-25T19:56:22.540 回答