134

I'm using Linq To XML

new XElement("Prefix", Prefix == null ? "" : Prefix)

but I want to do some computation to the prefix before adding it to the xml, like eliminating spaces, special chars, some calculations etc

I don't want to create functions because this ones won't be of any help on any other part of my program but this, so is there any way to create inline functions??

Igor Ševo
  • 5,459
  • 3
  • 35
  • 80
Joe Dixon
  • 1,557
  • 2
  • 10
  • 14
  • 6
    Dont prohibit yourself from creating a function just because it will not be called from any other place. Functions can also be used to clean up the code (if you have a large procedure spanning several pages breaking it into functions makes it more readable) and self document (just naming a function properly can convey information to the reader.) – Joe Mar 18 '16 at 13:17
  • 19
    If you came here from Google and want to know how to how to emulate inline functions in c#, go here: https://stackoverflow.com/questions/473782/inline-functions-in-c The answers below don't pertain to "inline" functions in the true sense of the word, and c# doesn't even have true inline functions but the link above provides a compiler optimization that can be used. – JamesHoux Mar 09 '18 at 16:56
  • Thanks James, the question title is rather misleading indeed. – Zar Shardan May 11 '18 at 12:45
  • 7
    If you came here from Google, and you don't want to dig -- just put this attribute: `[MethodImpl(MethodImplOptions.AggressiveInlining)]` – BrainSlugs83 Jan 27 '21 at 21:32

6 Answers6

294

Yes, C# supports that. There are several syntaxes available.

  • Anonymous methods were added in C# 2.0:

    Func<int, int, int> add = delegate(int x, int y)
    {
        return x + y;
    };
    Action<int> print = delegate(int x)
    {
        Console.WriteLine(x);
    }
    Action<int> helloWorld = delegate // parameters can be elided if ignored
    {
        Console.WriteLine("Hello world!");
    }
    
  • Lambdas are new in C# 3.0 and come in two flavours.

    • Expression lambdas:

      Func<int, int, int> add = (int x, int y) => x + y; // or...
      Func<int, int, int> add = (x, y) => x + y; // types are inferred by the compiler
      
    • Statement lambdas:

      Action<int> print = (int x) => { Console.WriteLine(x); };
      Action<int> print = x => { Console.WriteLine(x); }; // inferred types
      Func<int, int, int> add = (x, y) => { return x + y; };
      
  • Local functions have been introduced with C# 7.0:

    int add(int x, int y) => x + y;
    void print(int x) { Console.WriteLine(x); }
    

There are basically two different types for these: Func and Action. Funcs return values but Actions don't. The last type parameter of a Func is the return type; all the others are the parameter types.

There are similar types with different names, but the syntax for declaring them inline is the same. An example of this is Comparison<T>, which is roughly equivalent to Func<T, T, int>.

Func<string, string, int> compare1 = (l,r) => 1;
Comparison<string> compare2 = (l, r) => 1;
Comparison<string> compare3 = compare1; // this one only works from C# 4.0 onwards

These can be invoked directly as if they were regular methods:

int x = add(23, 17); // x == 40
print(x); // outputs 40
helloWorld(x); // helloWorld has one int parameter declared: Action<int>
               // even though it does not make any use of it.
Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 7
    I don't understand this answer. In his example, he wants new XElement("Prefix", prefix => newPrefix) declared inline. All of these answers amount to declaring a new function. Why not just declare a new function? – Matthew James Davis Jun 04 '13 at 17:26
  • 3
    because: 1. to undertand logic of method reading inline function is much easier than searching different declarations 2. frequently you need to write less code when using inline functions – Volodymyr Oct 03 '16 at 14:25
  • 1
    I'm using Unity3D which for all intensive out-of-the-box purposes is C# <= 3.0 so the 2.0+ history is appreciated – Jacksonkr Jan 30 '22 at 16:28
58

C# 7 adds support for local functions

Here is the previous example using a local function

void Method()
{
    string localFunction(string source)
    {
        // add your functionality here
        return source ;
    };

   // call the inline function
   localFunction("prefix");
}
DalSoft
  • 10,673
  • 3
  • 42
  • 55
  • 1
    How many times will that function be created? Will it be created only or each time I call the wrapper function? – qqqqqqq Jul 07 '21 at 07:35
  • Is it possible for the inline function to be a lambda function? – qqqqqqq Aug 02 '21 at 16:21
  • 1
    Yes from this example do `string localFunction(string source) => source;` Read the [sections](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions) on Definite assignment and Variable capture, this should answer your questions. – DalSoft Aug 04 '21 at 11:36
  • 1
    @qqqqqqq c# is statically typed, so the localfunction is only ever created once: at compile time. For Javascript, this would be a different story... the function would be created everytime the Method() function was called. – enorl76 Sep 10 '22 at 17:11
45

The answer to your question is yes and no, depending on what you mean by "inline function". If you're using the term like it's used in C++ development then the answer is no, you can't do that - even a lambda expression is a function call. While it's true that you can define inline lambda expressions to replace function declarations in C#, the compiler still ends up creating an anonymous function.

Here's some really simple code I used to test this (VS2015):

    static void Main(string[] args)
    {
        Func<int, int> incr = a => a + 1;
        Console.WriteLine($"P1 = {incr(5)}");
    }

What does the compiler generate? I used a nifty tool called ILSpy that shows the actual IL assembly generated. Have a look (I've omitted a lot of class setup stuff)

This is the Main function:

        IL_001f: stloc.0
        IL_0020: ldstr "P1 = {0}"
        IL_0025: ldloc.0
        IL_0026: ldc.i4.5
        IL_0027: callvirt instance !1 class [mscorlib]System.Func`2<int32, int32>::Invoke(!0)
        IL_002c: box [mscorlib]System.Int32
        IL_0031: call string [mscorlib]System.String::Format(string, object)
        IL_0036: call void [mscorlib]System.Console::WriteLine(string)
        IL_003b: ret

See those lines IL_0026 and IL_0027? Those two instructions load the number 5 and call a function. Then IL_0031 and IL_0036 format and print the result.

And here's the function called:

        .method assembly hidebysig 
            instance int32 '<Main>b__0_0' (
                int32 a
            ) cil managed 
        {
            // Method begins at RVA 0x20ac
            // Code size 4 (0x4)
            .maxstack 8

            IL_0000: ldarg.1
            IL_0001: ldc.i4.1
            IL_0002: add
            IL_0003: ret
        } // end of method '<>c'::'<Main>b__0_0'

It's a really short function, but it is a function.

Is this worth any effort to optimize? Nah. Maybe if you're calling it thousands of times a second, but if performance is that important then you should consider calling native code written in C/C++ to do the work.

In my experience readability and maintainability are almost always more important than optimizing for a few microseconds gain in speed. Use functions to make your code readable and to control variable scoping and don't worry about performance.

"Premature optimization is the root of all evil (or at least most of it) in programming." -- Donald Knuth

"A program that doesn't run correctly doesn't need to run fast" -- Me

Ray Fischer
  • 936
  • 7
  • 9
  • 8
    This is a top Google hit for inlining C# functions. You say "Maybe if you're calling it thousands of times a second", and guess what - I'm calling it 4 million times a second, so yeah ... inlining would probably be useful (and hugely increase code readability vs what I'm about to have to do: manual unrolling of one function in 16 places). – Adam Sep 16 '19 at 16:01
  • 1
    For those familiar with Kotlin, this means that Kotlin's `inline` functions have no equivalent in C#. – Vapid Nov 17 '20 at 12:20
18

Yes.

You can create anonymous methods or lambda expressions:

Func<string, string> PrefixTrimmer = delegate(string x) {
    return x ?? "";
};
Func<string, string> PrefixTrimmer = x => x ?? "";
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Thanks for your answer, could you elaborate a bit more on the answer, the lamba one, i mean the `code`Func PrefixTrimmer = x => x ?? "";`code` im new to this and i really dont understand very well the MSDN doc – Joe Dixon Feb 04 '11 at 16:16
  • 2
    @Joe: `x ?? ""` is the null-coalescing operator. http://msdn.microsoft.com/en-us/library/ms173224.aspx – SLaks Feb 04 '11 at 16:17
  • In `x => (something)`, `x` is a parameter, and `(something)` is the return value`. – SLaks Feb 04 '11 at 16:17
  • -1. http://en.wikipedia.org/wiki/Inline_function http://en.wikipedia.org/wiki/Nested_function – AK_ Feb 04 '11 at 16:21
  • 2
    @Hellfrost: Read the question. He's not asking about C++-style inline functions. I don't want to create functions because this ones won't be of any help on any other part of my program but this – SLaks Feb 04 '11 at 16:51
  • I understood what he wants(Nested Func). What he need's is a private method, mostly for the sake of clarity and brevity – AK_ Feb 04 '11 at 17:01
6

Not only Inside methods, it can be used inside classes also.

class Calculator
    {
        public static int Sum(int x,int y) => x + y;
        public static Func<int, int, int>  Add = (x, y) => x + y;
        public static Action<int,int> DisplaySum = (x, y) => Console.WriteLine(x + y);
    }
Deepak Mishra
  • 2,984
  • 1
  • 26
  • 32
6

You can use Func which encapsulates a method that has one parameter and returns a value of the type specified by the TResult parameter.

void Method()
{
    Func<string,string> inlineFunction = source => 
    {
        // add your functionality here
        return source ;
     };


    // call the inline function
   inlineFunction("prefix");
}
Homam
  • 23,263
  • 32
  • 111
  • 187