the question is in the title
You cannot declare a function as inline explicitly, but the JIT optimizer is free to inline functions if it sees the benefit.
The .NET team has wisely decided that such features have no place in the programming language itself since the compiler is better in deciding what to inline anyway. That's putting it rather aggressively but the fact is that modern C++ actually often disregard the inline
instruction for their decision-making process about which functions to inline.
The answers I've seen assume you're talking about compile or JIT-time inlining - and they're entirely correct. However, the other use of the word "inline" that I've heard is for things like lambda expressions - in C#, things like:
public IEnumerable<int> Foo()
{
int[] numbers = new[] { 1, 5, 2, 5, 6 };
return numbers.Select(x => x+10);
}
The x => x+10
(a lambda expression) can be regarded as an "inline function" in source code terms, in that it's an extra function declared "inline" in another method.
And yes, VB9 has this:
Dim len As Func(Of String, Integer) = Function(x) x.Length
Console.WriteLine(len("foo"))
I believe there are more restrictions in VB9 compared with C# though - for instance, I don't think you can create an Action<T>
(or any other delegate type with a void return type) using a lambda expression in VB, whereas it's easy in C#. Likewise I believe the lambda has to be just a single expression in VB, whereas in C# it can be a whole block in braces.
Of course, if the question was really referring to the execution rather than the source code, all of this is irrelevant :)
Inlining is the responsibility of the CLR (JIT) and there are some conditions as to when a function is inlined:
- The code size is smaller than 32 bytes of IL.
- The function does not contain "complex" constructs, e.g. loops, switch etc.
- The function does not contain try/catch/finally.
- The function is not declared as virtual.
As you will probably find out, 32 bytes is not very much in terms of code, it is suitable for quick and small if-else condition testing, property getters/setters. I don't think you can gain any speed from inlining a bigger amount of code.
Here's one scenario when it would be a nice facility:
We have a standard logging function to which it is often useful to pass the caller's name. However, if logging is set to a low verbosity, the logging function simply returns to aid performance. To avoid the caller making CPU-expensive calls to System.Reflection.MethodBase.GetCurrentMethod.Name, only for the logging function to not use them, it would be nice if we could create an inline function which decided in advance whether to bother finding out the method's name:
Public Inline Function GetMyname(iLogLevel) as string
if iLogLevel < 3 then return ""
return System.Reflection.MethodBase.GetCurrentMethod.Name()
End Function
Then in the caller, we could have put a neat line like:
Log(2,GetMyname(2) & ": Something happened")
But if the compiler decides not to inline GetMyname() (as it surely would) then the methodname that would appear in the log would always be "GetMyName" - no use at all.
Call me old fashioned, but if we start leaving all decisions to the compiler (or the CLR!) then we may as well look for a new career and leave it to "the .Net team". Sometimes, software designers DO actually know best?