C#中的内联函数?
如何在C#中实现“内联函数”?我想我不明白这个概念。它们像匿名方法吗?像lambda函数C#中的内联函数?,c#,optimization,inline,C#,Optimization,Inline,如何在C#中实现“内联函数”?我想我不明白这个概念。它们像匿名方法吗?像lambda函数 注意:答案几乎完全涉及到使用被调用方主体替换函数调用站点的手动优化或编译器优化。如果您感兴趣,请参阅或。内联方法只是一种编译器优化,其中函数的代码被滚动到调用方中 在C#中没有实现这一点的机制,而且在支持它们的语言中,它们的使用要谨慎——如果你不知道为什么它们应该在某个地方使用,它们就不应该被使用 编辑:为了澄清,有两个主要原因需要谨慎使用它们: 在不需要内联的情况下,使用内联很容易生成大量二进制文件 从性
注意:答案几乎完全涉及到使用被调用方主体替换函数调用站点的手动优化或编译器优化。如果您感兴趣,请参阅或。内联方法只是一种编译器优化,其中函数的代码被滚动到调用方中 在C#中没有实现这一点的机制,而且在支持它们的语言中,它们的使用要谨慎——如果你不知道为什么它们应该在某个地方使用,它们就不应该被使用 编辑:为了澄清,有两个主要原因需要谨慎使用它们:
最好别管它,让编译器完成它的工作,然后分析并确定内联是否是最适合您的解决方案。当然,有些事情是内联的(特别是数学运算符),但让编译器处理它通常是最佳实践。Lambda表达式是内联函数!我认为,C#没有内联之类的额外属性 > P>你是指C++中的内联函数吗?在其中,普通函数的内容自动内联复制到调用站点?最终的结果是,调用函数时实际上不会发生函数调用 例如:
inline int Add(int left, int right) { return left + right; }
static void Example() {
Func<int,int,int> add = (x,y) => x + y;
var result = add(4,6); // 10
}
如果是这样,那么就不存在与此等价的C
还是说在另一个函数中声明的函数?如果是,那么是的,C#通过匿名方法或lambda表达式支持这一点
例如:
inline int Add(int left, int right) { return left + right; }
static void Example() {
Func<int,int,int> add = (x,y) => x + y;
var result = add(4,6); // 10
}
static void示例(){
Func add=(x,y)=>x+y;
var result=add(4,6);//10
}
没错,唯一的区别是它返回一个值
简化(不使用表达式):
List.ForEach
执行一个操作,它不期望返回结果
因此,一个操作
委托就足够了。。说:
List<T>.ForEach(param => Console.WriteLine(param));
或
Function myFunction=theObject=>theObject.ToString();
字符串myString=myFunction(someObject);
我希望这有帮助。科迪说得对,但我想提供一个内联函数的例子 假设您有以下代码:
private void OutputItem(string x)
{
Console.WriteLine(x);
//maybe encapsulate additional logic to decide
// whether to also write the message to Trace or a log file
}
public IList<string> BuildListAndOutput(IEnumerable<string> x)
{ // let's pretend IEnumerable<T>.ToList() doesn't exist for the moment
IList<string> result = new List<string>();
foreach(string y in x)
{
result.Add(y);
OutputItem(y);
}
return result;
}
private void OutputItem(字符串x)
{
控制台写入线(x);
//也许可以封装额外的逻辑来决定
//是否还要将消息写入跟踪或日志文件
}
公共IList构建列表和输出(IEnumerable x)
{//让我们假设IEnumerable.ToList()暂时不存在
IList结果=新列表();
foreach(x中的字符串y)
{
结果:添加(y);
门诊(y);
}
返回结果;
}
compilerJust-In-Time优化器可以选择更改代码,以避免在堆栈上重复调用outputiItem(),这样就好像您编写的代码是这样的:
public IList<string> BuildListAndOutput(IEnumerable<string> x)
{
IList<string> result = new List<string>();
foreach(string y in x)
{
result.Add(y);
// full OutputItem() implementation is placed here
Console.WriteLine(y);
}
return result;
}
public IList BuildListAndOutput(IEnumerable x)
{
IList结果=新列表();
foreach(x中的字符串y)
{
结果:添加(y);
//完整的OutputItem()实现放在这里
控制台写入线(y);
}
返回结果;
}
在本例中,我们可以说OutputItem()函数是内联的。请注意,即使OutputItem()也是从其他地方调用的,它也可能执行此操作
编辑以显示更可能内联的场景。您混淆了两个不同的概念。函数内联是一种编译器优化,它对语义没有影响。无论函数是否为内联函数,其行为都是相同的 另一方面,lambda函数纯粹是一个语义概念。只要它们遵循语言规范中规定的行为,就不要求如何实现或执行它们。如果JIT编译器喜欢,它们可以内联;如果JIT编译器不喜欢,它们可以内联
C#中没有内联关键字,因为这是一种通常可以留给编译器的优化,特别是在JIT语言中。JIT编译器可以访问运行时统计信息,这使它能够比编写代码时更有效地决定内联什么。如果编译器决定内联函数,则函数将内联,而您对此都无能为力。:) 不,C#中没有这样的构造,但是.NET JIT编译器可以决定在JIT时间执行内联函数调用。但我实际上不知道它是否真的在做这样的优化。
(我认为它应该:-)C#不支持像python这样的动态语言那样的内联方法(或函数)。但是,匿名方法和lambda可以用于类似的目的,包括需要访问包含方法中的变量时,如下面的示例所示
static void Main(string[] args)
{
int a = 1;
Action inline = () => a++;
inline();
//here a = 2
}
更新:根据,以下内容适用于4.0及以下版本的.NET 您可以使用防止方法内联
[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
// ...
}
…但是没有办法做相反的事情,强制它内联。有时我确实希望强制代码内联 例如,如果我有一个复杂的例程,其中在一个高度迭代的块中有大量的决策,这些决策会导致执行类似但略有不同的操作。例如,考虑一个复杂的(非DB驱动)排序比较器,其中排序AlgRoRythm根据许多不同的不相关的标准对元素进行排序,如一个人可以根据语法和快速语言识别系统的语义标准来排序单词。我倾向于编写帮助函数来处理这些操作,以便维护
public IList<string> BuildListAndOutput(IEnumerable<string> x)
{
IList<string> result = new List<string>();
foreach(string y in x)
{
result.Add(y);
// full OutputItem() implementation is placed here
Console.WriteLine(y);
}
return result;
}
static void Main(string[] args)
{
int a = 1;
Action inline = () => a++;
inline();
//here a = 2
}
[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
// ...
}
// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices;
...
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)