Why is this delegate syntax "legal"? - c#

I am reading about anonymous methods and am trying to wrap my head around this example:
List<int> evenNumbers = list.FindAll(delegate(int i)
{ return (i % 2) == 0; } )
Why is delegate(int i) legal? You aren't having to declare new delegate void or anything like that.
Is that what is meant by anonymous method? Is this the added syntactic sugar that allows for anonymous methods?

It's legal because of what you suspect, it's creating an anonymous delegate/method.
An alternative (using the lambda operator =>) would be:
List<int> evenNumbers = list.FindAll((i) => ((i % 2) == 0));
or
List<int> evenNumbers = list.FindAll(i => i % 2 == 0);
See Lambda Expressions for further reading.

If you decompose the statement a little, hopefully it will be more obvious - this is the equivalent code.
Predicate<int> test = delegate(int i)
{
return (i % 2) == 0;
};
List<int> evenNumbers = list.FindAll(test);
As you can see it created an anonymous delegate (that the compiler will turn into a method behind the scenes)
Personally I've always found the "inline" anonymous delegate syntax to cloud the issue more than add clarity whereas the same construct built using a lambda expression, once you are used to the syntax, adds clarity
List<int> evenNumbers = list.FindAll(i => i % 2 == 0);

in this code it seems like passing a method into a method using a delegate.

Related

Inline function definition

For better readability, I want to define inline functions in C#, like this one:
var HasFullAccess = (mask => mask % 2 == 1);
foreach(AccessControlEntry ace in acl)
{
if(HasFullAccess(ace.AccessMask)) ...
The problem is the var. I guess I have to put sth. there that tells C# to expect a lambda expression? I also tried
(int => bool) HasFullAccess = (mask => mask % 2 == 1);
which also does not work. So how can I define an inline function?
You can do like this
Func<int,bool> HasFullAccess = mask => mask % 2 == 1;
You cannot assign a lambda expression to an implicitly-typed local variable (as the compiler should have pointed out). You will have to specify your delegate type (in this case Func<int, bool>) explicitly.
var HasFullAccess = new Func<int, bool>(mask => mask % 2 == 1);
Or, alternatively
Func<int, bool> HasFullAccess = mask => mask % 2 == 1;
like this
var hasFullAccess = new Func<int, bool>(mask => mask % 2 == 1);
or this,
Func<int, bool> hasFullAccess = mask => mask % 2 == 1;
for other types of function you'll need to use a compatible delegate type. You have to give the compiler some help.
Standard way to do this is to define this helper function:
public static Func<A, T> func<A, T>(Func<A, T> f)
{
return f;
}
somewhere in your namespace. Then you can call
var myfunc = func((int mask) => mask % 2 == 1);
and it will happily infer the type for you.

lambda expression foreach loop

I have the following code
int someCount = 0;
for ( int i =0 ; i < intarr.Length;i++ )
{
if ( intarr[i] % 2 == 0 )
{
someCount++;
continue;
}
// Some other logic for those not satisfying the condition
}
Is it possible to use any of the Array.Where or Array.SkiplWhile to achieve the same?
foreach(int i in intarr.where(<<condtion>> + increment for failures) )
{
// Some other logic for those not satisfying the condition
}
Use LINQ:
int someCount = intarr.Count(val => val % 2 == 0);
I definitely prefer #nneonneo's way for short statements (and it uses an explicit lambda), but if you want to build a more elaborate query, you can use the LINQ query syntax:
var count = ( from val in intarr
where val % 2 == 0
select val ).Count();
Obviously this is probably a poor choice when the query can be expressed with a single lambda expression, but I find it useful when composing larger queries.
More examples: http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
Nothing (much) prevents you from rolling your own Where that counts the failures. "Nothing much" because neither lambdas nor methods with yield return statements are allowed to reference out/ref parameters, so the desired extension with the following signature won't work:
// dead-end/bad signature, do not attempt
IEnumerable<T> Where(
this IEnumerable<T> self,
Func<T,bool> predicate,
out int failures)
However, we can declare a local variable for the failure-count and return a Func<int> that can get the failure-count, and a local variable is completely valid to reference from lambdas. Thus, here's a possible (tested) implementation:
public static class EnumerableExtensions
{
public static IEnumerable<T> Where<T>(
this IEnumerable<T> self,
Func<T,bool> predicate,
out Func<int> getFailureCount)
{
if (self == null) throw new ArgumentNullException("self");
if (predicate == null) throw new ArgumentNullException("predicate");
int failures = 0;
getFailureCount = () => failures;
return self.Where(i =>
{
bool res = predicate(i);
if (!res)
{
++failures;
}
return res;
});
}
}
...and here's some test code that exercises it:
Func<int> getFailureCount;
int[] items = { 0, 1, 2, 3, 4 };
foreach(int i in items.Where(i => i % 2 == 0, out getFailureCount))
{
Console.WriteLine(i);
}
Console.WriteLine("Failures = " + getFailureCount());
The above test, when run outputs:
0
2
4
Failures = 2
There are a couple caveats I feel obligated to warn about. Since you could break out of the loop prematurely without having walked the entire IEnumerable<>, the failure-count would only reflect encountered-failures, not the total number of failures as in #nneonneo's solution (which I prefer.) Also, if the implementation of LINQ's Where extension were to change in a way that called the predicate more than once per item, then the failure count would be incorrect. One more point of interest is that, from within your loop body you should be able to make calls to the getFailureCount Func to get the current running failure count so-far.
I presented this solution to show that we are not locked-into the existing prepackaged solutions. The language and framework provides us with lots of opportunities to extend it to suit our needs.

Linq late binding confusion

Can someone please explain me what I am missing here. Based on my basic understanding linq result will be calculated when the result will be used and I can see that in following code.
static void Main(string[] args)
{
Action<IEnumerable<int>> print = (x) =>
{
foreach (int i in x)
{
Console.WriteLine(i);
}
};
int[] arr = { 1, 2, 3, 4, 5 };
int cutoff = 1;
IEnumerable<int> result = arr.Where(x => x < cutoff);
Console.WriteLine("First Print");
cutoff = 3;
print(result);
Console.WriteLine("Second Print");
cutoff = 4;
print(result);
Console.Read();
}
Output:
First Print
1
2
Second Print
1
2
3
Now I changed the
arr.Where(x => x < cutoff);
to
IEnumerable<int> result = arr.Take(cutoff);
and the output is as follow.
First Print
1
Second Print
1
Why with Take, it does not use the current value of the variable?
The behavior your seeing comes from the different way in which the arguments to the LINQ functions are evaluated. The Where method recieves a lambda which captures the value cutoff by reference. It is evaluated on demand and hence sees the value of cutoff at that time.
The Take method (and similar methods like Skip) take an int parameter and hence cutoff is passed by value. The value used is the value of cutoff at the moment the Take method is called, not when the query is evaluated
Note: The term late binding here is a bit incorrect. Late binding generally refers to the process where the members an expression binds to are determined at runtime vs. compile time. In C# you'd accomplish this with dynamic or reflection. The behavior of LINQ to evaluate it's parts on demand is known as delayed execution.
There's a few different things getting confused here.
Late-binding: This is where the meaning of code is determined after it was compiled. For example, x.DoStuff() is early-bound if the compiler checks that objects of x's type have a DoStuff() method (considering extension methods and default arguments too) and then produces the call to it in the code it outputs, or fails with a compiler error otherwise. It is late-bound if the search for the DoStuff() method is done at run-time and throws a run-time exception if there was no DoStuff() method. There are pros and cons to each, and C# is normally early-bound but has support for late-binding (most simply through dynamic but the more convoluted approaches involving reflection also count).
Delayed execution: Strictly speaking, all Linq methods immediately produce a result. However, that result is an object which stores a reference to an enumerable object (often the result of the previous Linq method) which it will process in an appropriate manner when it is itself enumerated. For example, we can write our own Take method as:
private static IEnumerable<T> TakeHelper<T>(IEnumerable<T> source, int number)
{
foreach(T item in source)
{
yield return item;
if(--number == 0)
yield break;
}
}
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, int number)
{
if(source == null)
throw new ArgumentNullException();
if(number < 0)
throw new ArgumentOutOfRangeException();
if(number == 0)
return Enumerable.Empty<T>();
return TakeHelper(source, number);
}
Now, when we use it:
var taken4 = someEnumerable.Take(4);//taken4 has a value, so we've already done
//something. If it was going to throw
//an argument exception it would have done so
//by now.
var firstTaken = taken4.First();//only now does the object in taken4
//do the further processing that iterates
//through someEnumerable.
Captured variables: Normally when we make use of a variable, we make use of how its current state:
int i = 2;
string s = "abc";
Console.WriteLine(i);
Console.WriteLine(s);
i = 3;
s = "xyz";
It's pretty intuitive that this prints 2 and abc and not 3 and xyz. In anonymous functions and lambda expressions though, when we make use of a variable we are "capturing" it as a variable, and so we will end up using the value it has when the delegate is invoked:
int i = 2;
string s = "abc";
Action λ = () =>
{
Console.WriteLine(i);
Console.WriteLine(s);
};
i = 3;
s = "xyz";
λ();
Creating the λ doesn't use the values of i and s, but creates a set of instructions as to what to do with i and s when λ is invoked. Only when that happens are the values of i and s used.
Putting it all together: In none of your cases do you have any late-binding. That is irrelevant to your question.
In both you have delayed execution. Both the call to Take and the call to Where return enumerable objects which will act upon arr when they are enumerated.
In only one do you have a captured variable. The call to Take passes an integer directly to Take and Take makes use of that value. The call to Where passes a Func<int, bool> created from a lambda expression, and that lambda expression captures an int variable. Where knows nothing of this capture, but the Func does.
That's the reason the two behave so differently in how they treat cutoff.
Take doesn't take a lambda, but an integer, as such it can't change when you change the original variable.

Linq Index question

Can I write code like this with index
var someArray = new List<int>(){1,2,3,4,5};
var resultArray = someArray.Where((num, index) => index % 2 == 0);
like
var resultArray = from num in someArray...
I suppose you are asking "can I use query expression syntax to get at the overload of Where that provides the item index, in the way that I can using fluent method-chaining syntax".
The answer is no.
As seen in the docs for the no-index-parameter overload of Where :
In query expression syntax, a where clause translates to an invocation of Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>).
No, you cannot. There is no equivalent for the Where extension method allowing you to use the index using LINQ syntax.
The only way seems to be to hack around the problem:
var count = 0;
var resultArray = from num in someArray
let index = count++
where index % 2 == 0
select num;
Probably better to use the other syntax.

Why lambda here in the code?

i found a sample code where lambda was used the code as follows
var sumOfgreaterThanSeven = numbers.Sum(n => n > 7 ? n : 0);
but the above code can be written as
var sumOfgreaterThanSeven = numbers.Sum(n > 7 ? n : 0);
so why user write lambda. please help me to understand why user write lambda here.
also tell me what is the advantage of lambda. thanks
The lambda is because you want to evaluate the conditional expression per item n. The version you added (Sum(n > 7 ? n : 0)) can't work - n isn't defined anywhere (the compiler message should be "The name 'n' does not exist in the current context").
The lambda can be read as:
given a term n, if n is greater than 7 return n, else return 0
and then sum over that logic.
Re the advantage - firstly, convenience - but also composition. For example, with LINQ-to-SQL I would absolutely expect that to issue something like:
select sum(case when row.col > 7 then row.col else 0 end)
from sometable row
of course, it might be better to use:
var sumOfgreaterThanSeven = numbers.Where(n => n > 7).Sum();
which would map to
select sum(row.col)
from sometable row
where row.col > 7
which might hit an index more accurately
You need to think of Lambda Expressions as methods.
n => n > 7 ? n : 0
Can in fact be written as
(n) => {
if(n > 7)
return n;
else
return 0;
}
Lambda expression will be converted to an anonymous method and an instance of Func<> will be created from it.
UPDATE
As Marc pointed out, this conversion to anonymous method and instance of Func<> or Action does not always happen -as rightly pointed out in Linq-to-sql. ... - but here it does, hence I pointed out the underlying.
When you write a lambda you are calling a method or evaluating an expression. The left side of the => is a set of parameters passed into the method/expression on the right side.
IEnumerableThing.Where(a => DoSomeStuff(a))
It's like writing this:
foreach (var a in IEnumerableThing)
{
DoSomeStuff(a);
}
In the case of the Sum() method you are really doing something like this:
int mysum = 0;
foreach (var n in whatever)
{
if (n > 7) { mysum += n; }
}

Categories

Resources