You are on page 1of 15

Object Oriented Programming (C#) (CSE 321)

Lecture 9

Lambda Expressions, IEnumerable,


LINQ

Prepared by:
Dr. Ahmed Samy Moursi
Computer Science and Engineering Department
https://ahmedhashwa.github.io/
Quote of the day (1)

Lecture 9
CSE 321 Object Oriented Programming (C#) 2
Agenda

Lecture 9
CSE 321 Object Oriented Programming (C#) 3
Lambda
Expressions
Lambda Expressions

Lecture 9
◼ A lambda expression is an unnamed method written in place of a delegate instance.
◼ The compiler immediately converts the lambda expression to either of the following:
◼ A delegate instance.

◼ Example:

Transformer sqr = x => x * x; // lambda expression


Console.WriteLine(sqr(3)); // 9
delegate int Transformer(int i);
◼ An expression tree, of type Expression<TDelegate>, representing the code inside the
lambda expression in a traversable object model.
This allows the lambda expression to be interpreted later at runtime
◼ A lambda expression has the following form:
(parameters) => expression-or-statement-block
◼ For convenience, you can omit the parentheses if and only if there is exactly one
parameter of an inferable type.
◼ Here’s an example of an expression that accepts two parameters:
Func<string, string, int> totalLength = (s1, s2) => s1.Length + s2.Length;
int total = totalLength("hello", "world"); // total is 10;
◼ From C# 10, you can also specify the lambda return type: var sqr = int (int x) => x;

CSE 321 Object Oriented Programming (C#) 5


IEnumerable
IEnumerable and IEnumerator

Lecture 9
◼ The IEnumerator interface defines the basic low-level protocol by which elements
in a collection are traversed—or enumerated—in a forward-only manner.
◼ Its declaration is as follows:

◼ public interface IEnumerator {

bool MoveNext();
object Current { get; }
void Reset();
}
◼ Collections do not usually implement enumerators; instead, they provide
enumerators, via the interface IEnumerable:
public interface IEnumerable { IEnumerator GetEnumerator(); }
◼ The following example illustrates low-level use of IEnumerable and IEnumerator:

string s = "Hello";
// Because string implements IEnumerable, we can call GetEnumerator():
IEnumerator rator = s.GetEnumerator();
while (rator.MoveNext()) {
char c = (char)rator.Current;
Console.Write(c + ".");
}

CSE 321 Object Oriented Programming (C#) 7


IEnumerable and IEnumerator

Lecture 9
◼ However, it’s rare to call methods on enumerators directly in this manner because
C# provides a syntactic shortcut: the foreach statement.
◼ Here’s the same example rewritten using foreach:

string s = "Hello"; // The String class implements IEnumerable


foreach (char c in s)
Console.Write(c + ".");
◼ IEnumerator and IEnumerable are nearly always implemented in conjunction with

their extended generic versions:


public interface IEnumerator<T> : IEnumerator, IDisposable
{
T Current { get; }
}
public interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}

CSE 321 Object Oriented Programming (C#) 8


yield

Lecture 9
◼ The yield keyword in C# is a powerful feature used in conjunction with
the return keyword to specify that the method it is used in is an iterator
◼ Example:
foreach (var element in Data())
Console.WriteLine(element);
IEnumerable<string> Data(){

yield return "First";


yield return "Second";
yield return "Fourth";
yield return "Test";
}
◼ Another example:
foreach (var element in ProduceEvenNumbers(10))
Console.WriteLine(element);
IEnumerable<int> ProduceEvenNumbers(int upto) {
for (int i = 0; i <= upto; i += 2)
yield return i;
}

CSE 321 Object Oriented Programming (C#) 9


Iterators

Lecture 9
◼ Whereas a foreach statement is a consumer of an enumerator, an iterator is a
producer of an enumerator.
◼ In this example, we use an iterator to return a sequence of Fibonacci numbers
(where each number is the sum of the previous two):
◼ using System;
using System.Collections.Generic;
foreach (int fib in Fibs(6))
Console.Write (fib + " ");
IEnumerable<int> Fibs(int fibCount)
{
for (int i = 0, prevFib = 1, curFib = 1; i < fibCount; i++
)
{
yield return prevFib;
int newFib = prevFib + curFib;
prevFib = curFib;
curFib = newFib;
}
}

CSE 321 Object Oriented Programming (C#) 10


LINQ
LINQ

Lecture 9
◼ LINQ, or Language Integrated Query, is a set of language and runtime features for writing
structured type-safe queries over local object collections and remote data sources.
◼ LINQ enables you to query any collection implementing IEnumerable<T>, whether an

array, list, or XML Document Object Model (DOM), as well as remote data sources, such
as tables in an SQL Server database.
◼ LINQ offers the benefits of both compile-time type checking and dynamic query
composition.
◼ The basic units of data in LINQ are sequences and elements. A sequence is any object that

implements IEnumerable<T>, and an element is each item in the sequence.


◼ In the following example, names is a sequence, and "Tom", “Ahmed", and "Harry" are

elements:
string[] names = { "Tom", “Ahmed", "Harry" }; // local sequence
◼ A query operator is a method that transforms a sequence.

◼ A typical query operator accepts an input sequence and emits a transformed output
sequence.
◼ In the Enumerable class in System.Linq, there are around 40 query operators—all

implemented as static extension methods. These are called standard query operators.

CSE 321 Object Oriented Programming (C#) 12


LINQ

Lecture 9
◼ A query is an expression that, when enumerated, transforms sequences with query
operators. The simplest query comprises one input sequence and one operator.
◼ For instance, we can apply the Where operator on a simple array to extract those strings

whose length is at least four characters, as follows:


string[] names = { "Tom", "Ahmed", "Harry" };
IEnumerable<string> filteredNames = names.Where(n => n.Length >= 4);
foreach (string n in filteredNames)
Console.WriteLine(n);

◼ Another way to write this is:


string[] names = { "Tom", "Ahmed", "Harry" };
IEnumerable<string> filteredNames = from n in names
where n.Length >=4
select n;

CSE 321 Object Oriented Programming (C#) 13


LINQ Fluent Syntax

Lecture 9
◼ Example:
using System;
using System.Collections.Generic;
using System.Linq;
string[] names = { "Tom", "Ahmed", "Harry", "Mary", "Jay" };
IEnumerable<string> query = names
.Where(n => n.Contains("a"))
.OrderBy(n => n.Length)
.Select(n => n.ToUpper());
foreach (string name in query) Console.WriteLine(name);

CSE 321 Object Oriented Programming (C#) 14


Quote of the day (2)

Lecture 9
CSE 321 Object Oriented Programming (C#) 15

You might also like