你如何在C#中做“内联函数”?我不认为我理解这个概念 . 他们喜欢匿名方法吗?像lambda函数一样?
Note :答案几乎完全处理inline functions的能力,即"a manual or compiler optimization that replaces a function call site with the body of the callee."如果您对anonymous (a.k.a. lambda) functions感兴趣,请参阅@jalf's answer或What is this 'Lambda' everyone keeps speaking of? .
14 回答
最后在.NET 4.5中,CLR允许使用MethodImplOptions.AggressiveInlining值来提示/ suggest1方法内联 . 它也可以在Mono的后备箱中使用(今天提交) .
1 . 此前使用"force" . 由于有一些downvotes,我会试着澄清这个词 . 正如在评论和文档中那样,
The method should be inlined if possible.
特别是考虑到Mono(开放),考虑内联或更普遍的(如虚拟函数),存在一些特定于单一的技术限制 . 总的来说,是的,这是对编译器的暗示,但我想这就是要求的 .内联方法只是一种编译器优化,其中函数的代码被卷入调用者 .
在C#中没有任何机制可以做到这一点,并且它们在支持它们的语言中被谨慎使用 - 如果你不知道为什么它们应该被用在某个地方,它们就不应该被使用 .
编辑:澄清一下,有两个主要原因需要谨慎使用:
没有必要's easy to make massive binaries by using inline in cases where it'
从性能的角度来看,编译器往往比你应该知道更好
最好不要管它,让编译器完成它的工作,然后分析并确定内联是否是最适合你的解决方案 . 当然,有些事情只是有意义内联(特别是数学运算符),但让编译器处理它通常是最好的做法 .
Update: Per konrad.kruczynski's answer,以下版本适用于4.0及以下版本的.NET .
您可以使用MethodImplAttribute class来防止方法被内联...
......但是没有办法做相反的事情并迫使它被内联 .
你混淆了两个不同的概念 . 函数内联是一种编译器优化,它对语义没有影响 . 无论内联与否,函数的行为都相同 .
另一方面,lambda函数纯粹是一种语义概念 . 只要它们遵循语言规范中规定的行为,就不需要如何实现或执行它们 . 如果JIT编译器感觉如此,则可以内联它们,如果不是,则可以内联它们 .
C#中没有内联关键字,因为它是一种优化,通常可以留给编译器,特别是在JIT的语言中 . JIT编译器可以访问运行时统计信息,这使得它能够比编写代码时更有效地决定内联内容 . 如果编译器决定使用函数,那么无论如何都无法对它进行任何操作 . :)
你的意思是C语言中的内联函数吗?其中正常函数的内容会自动内嵌到调用点中?最终结果是在调用函数时实际上没有发生函数调用 .
例:
如果是,那么不,没有C#等同于此 .
或者你的意思是在另一个函数中声明的函数?如果是,那么是的,C#通过匿名方法或lambda表达式支持这一点 .
例:
Cody说得对,但我想提供一个内联函数的例子 .
假设你有这个代码:
compilerJust-In-Time优化器可以选择更改代码以避免重复调用堆栈上的OutputItem(),这样就好像你已经编写了这样的代码:
在这种情况下,我们会说OutputItem()函数是内联的 . 请注意,即使从其他位置调用OutputItem(),它也可能会这样做 .
编辑以显示更可能被内联的场景 .
是的确,唯一的区别是它返回一个值 .
简化(不使用表达式):
List<T>.ForEach
采取行动,它不期望返回结果 .所以
Action<T>
代表就足够了..说:和说:
区别在于param类型和委托decleration是由用法推断的,并且在简单的内联方法中不需要括号 .
在哪里
List<T>.Where
采用函数,期待结果 .所以预计
Function<T, bool>
:这与:
您还可以内联声明这些方法并将它们与变量IE一起对齐:
要么
我希望这有帮助 .
在某些情况下,我确实希望强制代码嵌入 .
例如,如果我有一个复杂的例程,在高度迭代的块中做出大量的决策,那些决策会导致执行类似但略有不同的操作 . 例如,考虑一个复杂的(非DB驱动的)排序比较器,其中排序algorythm对元素进行排序根据许多不同的无关标准,例如,如果他们根据快速语言识别系统的语法和语义标准对单词进行排序,则可能会这样做 . 我倾向于编写辅助函数来处理这些操作,以保持源代码的可读性和模块性 .
我知道那些辅助函数应该是内联的,因为如果代码永远不需要被人理解,那就是编写代码的方式 . 在这种情况下,我当然希望确保没有函数调用开销 .
声明“最好把这些事情单独留下,让编译器完成工作......”(Cody Brocious)是完全无懈可击的 . 我已经编写了20年的高性能游戏代码,我还没有遇到一个“足够智能”的编译器,无法知道哪些代码应该内联(函数) . 在c#中使用“内联”语句会很有用,事实是,如果没有“内联”提示,编译器就不会拥有确定哪个函数应该始终内联所需的所有信息 . 当然,如果函数很小(访问器),那么它可能会自动内联,但如果只是几行代码呢?毫无疑问,编译器无法知道,你不能把它留给编译器来优化代码(超出算法) .
不,C#中没有这样的构造,但.NET JIT编译器可以决定在JIT时间进行内联函数调用 . 但我实际上不知道它是否真的在做这样的优化 .
(我认为应该:-))
如果您的程序集将被添加,您可能需要查看TargetedPatchingOptOut . 这将有助于ngen决定是否内联方法 . MSDN reference
尽管如此,它仍然只是一个声明性的提示,而不是命令性命令 .
我知道这个问题是关于C#的 . 但是,您可以使用F#在.NET中编写内联函数 . 见:Use of
inline
in F#C#不像python这样的动态语言支持内联方法(或函数) . 但是,匿名方法和lambdas可用于类似目的,包括当您需要访问包含方法中的变量时,如下例所示 .
Lambda表达式是内联函数!我认为,C#没有像内联或类似的额外属性!