Despite the fact that I will focus on the first point, I start by giving 2 cents for the entire production output. If the differences are not significant or the intensity of use, I usually do not worry about microseconds, which when added do not represent any visible difference to the user. I emphasize that I don't care if we consider non-intensive callable methods. Where I have specific performance considerations, I develop the application myself. I care about caching, about using threads, about smart ways to call methods (make multiple calls or try to make only one call), whether to connect connections or not, etc. Etc. In fact, I usually focus on raw performance, but on scalability. I don't care if it works better for a tiny bit of a nanosecond for a single user, but I really like being able to boot the system with a lot of concurrent users without noticing the impact.
Having said that, here is my opinion on paragraph 1. I love anonymous methods. They give me great flexibility and code elegance. Another great feature of anonymous methods is that they allow me to directly use local variables from the container method (from the point of view of C #, and not from the point of view of IL, of course). They save me from downloading code. When do I use anonymous methods? Evey at a time, the part of the code that I need is not needed elsewhere. If it is used in two different places, I don't like copy-paste as a reuse method, so I use a simple delegate. So, as Shoosh replied, it's nice to have code duplication. In theory, there are no differences in performance, since anonyms are C # tricks, not IL things.
Most of what I think of anonymous methods relates to lambda expressions, since the latter can be used as compact syntax for representing anonymous methods. Take the following method:
public static void DoSomethingMethod(string[] names, Func<string, bool> myExpression) { Console.WriteLine("Lambda used to represent an anonymous method"); foreach (var item in names) { if (myExpression(item)) Console.WriteLine("Found {0}", item); } }
He receives an array of strings and for each of them, he will call the method passed to him. If this method returns true, it will say "Found ...". You can call this method as follows:
string[] names = {"Alice", "Bob", "Charles"}; DoSomethingMethod(names, delegate(string p) { return p == "Alice"; });
But you can also call it like this:
DoSomethingMethod(names, p => p == "Alice");
In IL, there is no difference between the one who uses the Lambda expression is much readable. Once again, the performance impact is not affected, since all these are C # compiler tricks (and not JIT compiler tricks). Just as I did not feel that we were abusing anonymous methods, I did not feel that we were abusing lambda expressions to represent anonymous methods. Of course, the same logic applies to re-code: don't do lambda, use persistent delegates. There are other restrictions that lead you to anonymous methods or simple delegates, such as out or ref argument.
Another nice thing about Lambda expressions is that the same syntax should not represent an anonymous method. Lambda expressions can also represent ... you guessed it, expressions. Take the following example:
public static void DoSomethingExpression(string[] names, System.Linq.Expressions.Expression<Func<string, bool>> myExpression) { Console.WriteLine("Lambda used to represent an expression"); BinaryExpression bExpr = myExpression.Body as BinaryExpression; if (bExpr == null) return; Console.WriteLine("It is a binary expression"); Console.WriteLine("The node type is {0}", bExpr.NodeType.ToString()); Console.WriteLine("The left side is {0}", bExpr.Left.NodeType.ToString()); Console.WriteLine("The right side is {0}", bExpr.Right.NodeType.ToString()); if (bExpr.Right.NodeType == ExpressionType.Constant) { ConstantExpression right = (ConstantExpression)bExpr.Right; Console.WriteLine("The value of the right side is {0}", right.Value.ToString()); } }
Pay attention to a slightly different signature. The second parameter receives the expression, not the delegate. The way to call this method:
DoSomethingExpression(names, p => p == "Alice");
This is exactly the same as the call that we created when creating the anonymous method using lambda. The difference here is that we are not creating an anonymous method, but creating an expression tree. It is because of these expression trees that we can then translate lambda expressions into SQL, which, for example, does Linq 2 SQL, instead of launching material in the engine for each sentence, such as Where, Select, etc. The good thing is that the call syntax is the same regardless of whether you create an anonymous method or send an expression.