C# method group strangeness - c#

I discovered something very strange that I'm hoping to better understand.
var all = new List<int[]>{
new int[]{1,2,3},
new int[]{4,5,6},
new int[]{7,8,9}
};
all.ForEach(n => n.ForEach(i => Console.WriteLine(i)));
which can be rewritten as:
...
all.ForEach(n => n.ForEach(Console.WriteLine));
How is it possible to leave out the lambda expression parameter (i=>) and still have the current item passed to console.WriteLine?
Thanks for any insight.
-Keith

List<T>.ForEach is looking for an Action<T>. When you write
n.ForEach(Console.WriteLine);
what you have here is one of the members of the method group Console.WriteLine playing the role of an Action<T>. The compiler will look for the best overload of Console.WriteLine that eats instances of int. In fact, it will use the overload Console.WriteLine(int). It will then use this overload to play the role of an Action<int>.
For details on how this is done, see §6.6 of the specification (Method group conversions).
However, when you write
n.ForEach(i => Console.WriteLine(i));
we actually have a very different Action<int> In the first case, the Action<int> was Console.WriteLine(int). Here, the Action<int> is equivalent to you having written
public static void DoSomething(int i) {
Console.WriteLine(i);
}
and then
n.ForEach(DoSomething);
(Of course, the compiler has to go through the same method group process as described above to figure out what is meant by DoSomething).
The point is that in the first case the Action<int> is Console.WriteLine(int). However, in the second case the Action<int> is a middle man (the lambda expression) that itself will call Console.WriteLine(int).

This is less confusing if you consider what is really happening.
You are passing a method to a delegate argument. Most of the time, we think of delegates in the context of events, but they can be parameters to methods as well. It doesn't seem odd when a method is added to an event without arguments, it just is unusual looking when executed in this context.
Before lambdas, you had to do this all the time, and it was such a pain that one would never consider using a library that looked like LINQ. With Lambdas, this is easier to do, but you can always do the old way as well.

Related

use delegate (or other) to do the same thing as lambda operator [duplicate]

I'm new to SO and programming and learning day by day with bits and pieces of tech (C#) jargons.
After Googling for a while, below is what I've researched about methods
A Method is a block of statements, which serves for code reusability
& it also supports overloading with different SIGNATURE....for ex:
drawShape(2pts), drawShape(3pts) etc...
An Anonymous method is one with block of statements, but no
name....(as its premature to ask, in wt situation we come across
anonymous method...any articles, samples ...)
Named method: Here's a link but at the end i didn't get what Named Method actually is...
Can anyone explain what a "Named" method is, and where do we use anonymous method?
A named method is a method you can call by its name (e.g. it is a function that has a name). For example, you have defined a function to add two numbers:
int f(int x, int y)
{
return x+y;
}
You would call this method by its name like so: f(1, 2);.
Anonymous method is a method that is passed as an argument to a function without the need for its name. These methods can be constructed at runtime or evaluated from a lambda expression at compile time.
These methods are often used in LINQ queries, for example:
int maxSmallerThan10 = array.Where(x => x < 10).Max();
The expression x => x < 10 is called a lambda expression and its result is an anonymous function that will be run by the method Where.
If you are a beginner, I would suggest you first read about more basic stuff. Check out the following links:
http://www.completecsharptutorial.com/
http://www.csharp-station.com/tutorial.aspx
http://www.homeandlearn.co.uk/csharp/csharp.html
Let's start from a simple method.
void MyMethod()
{
Console.WriteLine("Inside MyMethod"); //Write to output
}
The above method is a named-method which just writes Inside MyMethod to the output window.
Anonymous methods are some methods used in some special scenarios (when using delegates) where the method definition is usually smaller where you don't specify the name of the method.
For example, (delegate) => { Console.WriteLine("Inside Mymethod");}
Just start writing some simple programs and in the due course, when you use delegates or some advanced concepts, you will yourself learn. :)
Explanation by Analogy
Normally when we tell stories we refer to people by name:
"Freddie"
"Who's Freddie?"
"You know, Freddie, Freddie from Sales - the male guy with the red hair, who burned the building down...?"
In reality nobody cares who the person is, department he works etc. it's not like we'll refer to him every again. We want to be able to say: "Some guy burned down our building". All the other stuff (hair color, name etc.) is irrelevant and/or can be inferred.
What does this have to do with c#?
Typically in c# you would have to define a method if you want to use it: you must tell the compiler (typically):
what it is called,
and what goes into it (parameters + their types),
as well as what should come out (return type),
and whether it is something you can do in the privacy of your home or whether you can do it in public. (scope)
When you do that with methods, you are basically using named methods. But writing them out: that's a lot of effort. Especially if all of that can be inferred and you're never going to use it again.
That's basically where anonymous methods come in. It's like a disposable method - something quick and dirty - it reduces the amount you have to type in. That's basically the purpose of them.
Anonymous methods or anonymous functions, what seems to be the same, basically are delegates. As the link you point out: http://msdn.microsoft.com/en-us/library/bb882516.aspx describes, anonymous methods provide a simplified way to pass method to be executed by another method. Like a callback.
Another way to see it, is think about lambda expressions.
A named by the contrast is any common method.
From MSDN:
A delegate can be associated with a named method. When you instantiate a delegate by using a named method, the method is passed as a parameter. This is called using a named method. Delegates constructed with a named method can encapsulate either a static method or an instance method. Named methods are the only way to instantiate a delegate in earlier versions of C#. However, in a situation where creating a new method is unwanted overhead, C# enables you to instantiate a delegate and immediately specify a code block that the delegate will process when it is called. The block can contain either a lambda expression or an anonymous method.
and
In versions of C# before 2.0, the only way to declare a delegate was to use named methods. C# 2.0 introduced anonymous methods and in C# 3.0 and later, lambda expressions supersede anonymous methods as the preferred way to write inline code. However, the information about anonymous methods in this topic also applies to lambda expressions. There is one case in which an anonymous method provides functionality not found in lambda expressions. Anonymous methods enable you to omit the parameter list. This means that an anonymous method can be converted to delegates with a variety of signatures. This is not possible with lambda expressions. For more information specifically about lambda expressions, see Lambda Expressions (C# Programming Guide). Creating anonymous methods is essentially a way to pass a code block as a delegate parameter. By using anonymous methods, you reduce the coding overhead in instantiating delegates because you do not have to create a separate method.
So in answer to your question about when to use anonymous methods, then MSDN says: in a situation where creating a new method is unwanted overhead.
In my experience it's more down to a question of code reuse and readability.
Links:
http://msdn.microsoft.com/en-us/library/98dc08ac.aspx
http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx
Hope that helps

Passing a Delegate[] to a method

I am trying to desconstruct a method written by another coder to see how it works but it's getting a bit confusing
We have a Delegate that takes an Action as parameter.
private delegate void FunctionDelegate(Action next);
A function is then called in the constructor that takes an array of these delegates as parameter and executes each value in the array
LoadInSeries(LoadRoleAreaHours, LoadTableData);
The Function looks like this
private void LoadInSeries(params FunctionDelegate[] _delegates)
{
var Delegates = new List<FunctionDelegate>(_delegates);
Func<Action, Action> creator = null;
creator = delegate(Action inner)
{
if (Delegates.Count > 0)
{
FunctionDelegate L = Delegates.First();
Delegates.RemoveAt(0);
Action next = delegate { L(inner); };
return creator(next);
}
else return inner;
};
Action outer = creator(null);
if (outer != null)
outer();
}
The intent was too chain a series of functions with each function calling the next but wouldnt it just be easy to use a multicast delegate and add each function to the invocation list.
Does this code do something different?
Without a good Minimal, Complete, and Verifiable code example, it's impossible to understand the code fully. Of most significant concern is that your code example includes a mysterious L() method, the behavior of which we have no idea. There is also the problem with the FunctionDelegate = Delegates.First(); statement. At best, the FunctionDelegate identifier refers to a class field or property; at worst, that statement won't even compile. Either way, there's no evidence that the delegate object being removed from the input list is ever actually invoked.
So to even answer the question, some basic assumptions have to be made, which may or may not be correct.
That said, in the best-case scenario — which is that the code has hidden some awful, convoluted mechanism in the L() method that ultimately winds up able to invoke the delegate for the current call to the creator delegate — the code you're looking at is not simply invoking delegates in sequence, as would be the case with a MulticastDelegate. Rather, the code is constructing a chain of calls to the L() method, passing each delegate instance to the method in sequence.
Since you didn't show us the L() method, there's no way to say what the code actually does. I would agree that if all that L() does is invoke the delegate you pass to it, then this code looks like a very complicated way to just invoke an array of delegates. But, giving the benefit of the doubt to the person who wrote the code, this simply means that L() probably does something other than simply invoke the delegate.
Of course, it's possible the author of the code doesn't deserve the benefit of the doubt. In that case, not only would it be simpler to just use a multicast delegate, the simplest implementation would just iterate over the array, invoking each delegate in the desired sequence. But I say that without really knowing what the code does. I'm just assuming it's intended to do something useful with the delegates that are passed to it. There's no evidence in the code you posted to support even that generous assumption.
Give us the full picture, and a more definitive answer can be provided. Without knowing what L() is, or what side effects might exist in the passed-in delegates' target methods, it's impossible to say for sure whether the code you're looking at really needs to be written that way or not.

ForEach extension method

I'm a bit confused over a line of code:
Enumerable.Range(1,10).ToList().ForEach(Console.WriteLine);
This line does what it says it does, it prints out each number from 1 to 10 with a line break inbetween each of them, all that with one neat little line of code..
Now I'm only a C# novice at best, but it looks completely foreign to me, how can we call Console.WriteLine() without providing it with any arguments? How does it know what it's going to print? From this syntax it's not even clear to me that we're calling on a method (considering the lack of paranthesis around WriteLine).
I'm assuming that there's a lot of stuff going on "behind the scenes" here but I'm not very good at reading IL code, from what I've gathered reading the MSIL it seems like ForEach calls a generic delegate(System.Action) on each element in the collection, I am guessing that it then passes the element as an argument to the System.Action delegate but that's only my guess..
There is an implicit conversion from a method group (Console.WriteLine in this case) and a compatible delegate type. You code is effectively the same as
Action<int> f = Console.WriteLine;
Enumerable.Range(1,10).ToList().ForEach(f);
The delegate f is compatible with the method void Console.WriteLine(int)
Enumerable.Range(1,10).ToList().ForEach(Console.WriteLine)
is short for
Enumerable.Range(1,10).ToList().ForEach(text => Console.WriteLine(text));
it is called a MethodGroup
Foreach statement is a generic one, and in your case it is a ForEach<int>. It takes one argument of type Action<int> and any void method accepting single int parameter will work for this purpose. Console.WriteLine is one of such methods

Using Anonymous method not preferred by .NET itself?

I am trying to learn the anonymous method and tried out this sample.
So, whenever I am trying to call WriteLog function i can just use
()=> { return "someLogData" };
The advantage is that, I need not have a separate function and can save lines of code.
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
But, the same does not work out with functions like
Console.WriteLine( ()=> {return "someString" } );
Why does .NET provide this anonymous method functionality but does not let to use it in one of its own kind?
There are no overloads of Console.WriteLine which accept a Func<string> - and indeed even your current WriteLog method won't do anything useful (as you'd need to invoke the delegate).
Where methods accepting specific delegates do exist - most prominently in LINQ, but elsewhere too - you can indeed use lambda expressions or anonymous methods to invoke them.
You can call Console.WriteLine using a lambda expression, but you need to cast it to a specific delegate type - as there are only conversions from lambda expressions to specific delegate or expression types, not just Delegate or object. So this will work:
Console.WriteLine((Func<string>)(() => "someLogData"));
Again though, it wouldn't be useful to do so anyway - you don't want to log the delegate, you want to log the result of invoking the delegate.
It doesn't make very much sense for Console.WriteLine to accept delegates IMO, but it would make more sense for more flexible logging, where you don't want to evaluate the string unless you're actually going to write it to a log.
Note that your WriteLog call itself can be simpler too:
WriteLog(() => "someLogData");
You need to have your anonymous method executed to get the string.
public void WriteLog(Func<string> s)
{
Console.WriteLine(s());
}
There is an advantage in this form:
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
let's imagine that inside it it's written as:
public void WriteLog(Func<string> s)
{
if (needToWriteLog)
{
Console.WriteLine(s);
}
}
now, let's say that you call it this way:
WriteLog(() => StringThatNeedsFiveSecondsToBuild())
and let's compare it to a similar WriteLog that only accepts a string as a parameter:
WriteLog(StringThatNeedsFiveSecondsToBuild())
The second WriteLog will always spend 5 seconds to build the string, even when needToWriteLog is false, while the first one will build it only if it's true.
Now, compare it to Console.WriteLine: Console.WriteLine will always print its content, so there is no need to use a delegate, because the 5 seconds will always be spent.
There are some methods that are similar in C#, the ones of the family Debug.* and Trace.*, but they are different. You use them like this:
Debug.WriteLine(StringThatNeedsFiveSecondsToBuild())
the trick is that they are defined like this:
[ConditionalAttribute("DEBUG")]
public static void WriteLine(string value)
so that if the DEBUG isn't defined, the whole Debug.WriteLine(StringThatNeedsFiveSecondsToBuild()) is removed, even if it had some side effects (like spending 5 seconds :-) )
All of this show something else: it's VERY important that the delegates you pass to your WriteLog AND the parameters you pass to the Debug.* and Assert.* be side effect free (clearly ignoring the time as a side effect, I mean "real" side effects like changing variable values), because you don't know if they'll really be executed.

Func<T, TResult> delegate real world uses

I've recently been playing around with the delegate Func<T, TResult> and creating methods that return different instances Func<T, TResult> containing lambda but what I have struggled to come up with is any good real world ideas of why one might want to return (or even create such an instance).
There is an example on MSDN where they do the following...
Func<string, string> convertMethod = UppercaseString;
private static string UppercaseString(string inputString)
{
return inputString.ToUpper();
}
And although it looks pretty and is an interesting concept I fail to see what advantages such code provides.
So could someone here please provide any real world examples where they have had to use Func<T, TResult> and in general why one might want to use this delegate?
If what you're asking, really, is why we have delegates in general:
If you've ever consumed an event, you've used a delegate
If you've ever used LINQ, you've used a delegate (technically, with an IQueryable provider you've used an expression, but for LINQ-to-Objects you've used a delegate)
Delegates provide a way of injecting your own behavior into another object. The most common usage is with events. An object exposes an event and you provide a function (anonymous or not) that gets called when that event fires.
If you're asking why we have the Func<T, TResult> (and similar) delegate, then there are two main reasons:
People were having to declare their own simple delegate types when they needed a particular delegate in their code. While the Action<> and Func<> delegates can't cover all cases, they are simple to provide and cover many of the cases where custom delegates were needed.
More importantly, the Func<T, TResult> delegate is used extensively in LINQ-to-Objects to define predicates. More specifically, Func<T, bool>. This allows you to define a predicate that takes a strongly-typed member of an IEnumerable<T> and returns a boolean by using either a lambda or ordinary function, then pass that predicate to LINQ-to-Objects.
You would use it a lot in LINQ. So, for example, to double all the numbers in a list:
myList.Select(x => x * 2);
That's a Func<TIn, TOut>. It's quite useful when creating concise code. A real-world example is in one of the many tower-defence games I made, I calculated the closest enemy to the tower using one line:
enemies.Select(x => tower.Location.DistanceTo(x.Location)).OrderBy(x => x).FirstOrDefault();
I think a great example is lazy initialization.
var value = new Lazy<int>(() => ExpensiveOperation()); // Takes Func<T>
The canonical example of a need for a function pointer is for a comparison function to pass to a sort routine. In order to have different sort keys, you create a lambda for the comparison function, and pass that to the sort function.
Or for a simple real-world example:
IEnumerable<Person> FindByLastName(string lastName)
{
return Customers.Where(cust => cust.LastName == lastName);
}
In this example, cust => cust.LastName == lastName is not just a lambda, but it creates a closure by capturing the lastName parameter. In othe words, it creates a function, which will be different every time FindByLastName is called.
The Func<T> delegate (and other overloads) give you new ways for writing abstractions in C#. To demonstrate some of the options, here are a couple of C# langauge constructs that could be written using delegates instead:
Thread.Lock(obj, () => {
// Safely access 'obj' here
});
Enumerable.ForEach(collection, element => {
// Process 'element'
});
Exceptions.Try(() => {
// Try block
}).With((IOException e) => {
// Handle IO exceptions
});
These are quite primitive, so it is good to have a language construct for them. However, it demonstrates that Func and lambda expressions add quite a lot of expressive power. It makes it possible to write new constructs such as parallel loop (using .NET 4.0):
Parallel.ForEach(collection, element => {
// Process 'element'
});
First of all, Func<T> is not a class, it's a delegate.
Basically, you can use it whenever you need a method argument or a property of delegate type if you don't want to declare your own delegate for that.
One great use of Funct<T>, besides the fact that it is embedded in many frameworks such as LINQ, Mocking Tools, and Dependency Injection containers is to use it to create a delegate based factory.
Recently, I wanted the external program calling my method to be able to modify the way it behaves.
My method in itself simply converts a file from XLS to XML. But it was necessary to allow the calling code to specify if needed an arbitrary number of transformations which should apply to each xls cell before being writing as a xml tag. For example : convert the "," decimal separator to ".", suppress the thousand separator, and so on (the transformations were all string replacements).
Then the caller code just had to add an arbitrary number of entries in a dictionary where the key is the pattern and the value is the replacement string for this pattern. My method loops over the dictionary and creates a new Func<string,string> for each entry. Then for each cell the Func<string,string> are applied in sequence.

Categories

Resources