Extension Methods, Lambda Expressions and LINQ
Telerik Academy Alpha
Table of contents
Extension methods
What are extension methods?
-
Once a type is defined and compiled into an assembly its definition is, more or less, final
- The only way to update, remove or add new members is to re-code and recompile the code
-
Extension methods allow existing compiled types to gain new functionality
- Without recompilation
- Without touching the original assembly
Defining Extension Methods
-
Extension methods
- Defined in a static class
- Defined as static
- Use the this keyword before its first argument to specify the class to be extended
-
Extension methods are "attached" to the extended class
- Can also be called statically through the defining static class
Extension Methods – Examples
Extension Methods – Examples
Anonymous Types
Anonymous Types
-
Anonymous types
- Encapsulate a set of read-only properties and their value into a single object
- No need to explicitly define a type first
-
To define an anonymous type
- Use of the var keyword in conjunction with the object initialization syntax
var point = new { X = 3, Y = 5 };
Anonymous Types - Example
- At compile time, the C# compiler will autogenerate an uniquely named class
-
The class name is not visible from C#
- Using implicit typing (var keyword) is mandatory
var myCar = new { Color = "Red", Brand = "Tesla", TopSpeed = 270 };
Console.WriteLine("My car is a {0} {1}.", myCar.Color, myCar.Brand);
- Use an anonymous type to represent a car:
Anonymous Types - Properties
var p = new { X = 3, Y = 5 };
var q = new { X = 3, Y = 5 };
Console.WriteLine(p == q); // false
Console.WriteLine(p.Equals(q)); // true
- Anonymous types are reference types directly derived from System.Object
-
Have overridden version of Equals(), GetHashCode(), and ToString()
- Do not have == and != operators overloaded
Anonymous Types - Properties
var arr = new[]
{
new { X = 3, Y = 5 },
new { X = 1, Y = 2 },
new { X = 0, Y = 7 }
};
foreach (var item in arr)
{
Console.WriteLine("({0}, {1})", item.X, item.Y);
}
- You can define and use arrays of anonymous types through the following syntax:
Delegates
What are Delegates?
- Delegates are special .NET types that hold a method reference
-
Describe the signature of given method
- Number and types of the parameters
- The return type
-
Their "values" are methods
- These methods match their signature (parameters and return types)
- Delegates are reference types
What are Delegates?
-
Delegates are roughly similar to function pointers in C++
- Strongly-typed pointer (reference) to a method
- Pointer (address) to a callback function
- Can point to static and instance methods
-
Can point to a sequence of multiple methods
- Known as multicast delegates
- Used to perform callback invocations
- Implement the "publish-subscribe" model
Delegates - Example
Generic Delegates
- A delegate can be generic:
public delegate void SomeDelegate<T>(T item);
- Using a generic delegate:
public static void Notify(int i) { … }
SomeDelegate<int> d = new SomeDelegate<int>(Notify);
- The above can simplified as follows:
SomeDelegate<int> d = Notify;
Multicast Generic Delegates - Example
Predefined Delegates
-
Predefined delegates in .NET:
- Action<T1,T2> - generic predefined void delegate with parameters of types T1 and T2.
- Func<T1,T2,TResult> - generic predefined delegate with return value of type TResult
- Both overloads can accept from 1 to 16 parameter of Tn types.
Func<string, int> predefinedIntParse = int.Parse;
int number = predefinedIntParse("50");
Action<object> predefinedAction = Console.WriteLine;
predefinedAction(1000);
Events
What are Events?
- A message sent by an object to signal the occurrence of an action
-
Enable a class or object to notify other classes or objects when something of interest occurs
-
Publisher – the class that sends/raises the event
- Doesn’t know which object/method will handle the event
- Subscribers – the classes that receive/handle the event
-
Publisher – the class that sends/raises the event
- In .NET, events are based on the EventHandler delegate and the EventArgs base class
Define Events
- Use the event keyword
- Specify type of delegate for the event – EventHandler
-
Add a protected virtual method
- Name the method On[EventName]
class Counter {
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e) {
if (this.ThresholdReached != null) {
this.ThresholdReached(this, e);
}
}
}
Event Data
- Data that is associated with an event can be provided through an event data class
-
EventArgs class is the base type for all event data classes
- Also used when an event does not have any data associated with it
- Naming of the data class – [Name]EventArgs
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
Event Handlers
-
To respond to an event, you define an event handler method
- Must match the signature of the delegate
class Example {
static void Main() {
Counter counter = new Counter();
counter.ThresholdReached += CounterThresholdReached;
}
static void CounterThresholdReached(object sender, EventArgs e) {
Console.WriteLine("The threshold was reached.");
}
}
Lambda Expressions
What are Lambda Expressions?
-
A lambda expression is an anonymous function containing expressions and statements
- Used to create delegates or expression tree types
-
Lambda expressions
-
Use the lambda operator =>
- Read as "goes to"
- The left side specifies the input parameters
- The right side holds the expression or statement
-
Use the lambda operator =>
Lambda Expressions - Example
Lambda Expressions - Example Sorting
Delegates Holding Lambda Functions
-
Lambda functions can be stored in variables of type delegate
- Delegates are typed references to functions
-
Standard function delegates in .NET:
- Func<TResult>, Func<T,TResult>, Func<T1,T2,TResult>
Func<bool> boolFunc = () => true;
Func<int, bool> intFunc = (x) => x < 10;
if (boolFunc() && intFunc(5))
{
Console.WriteLine("5 < 10");
}
Predicates
- Predicates are predefined delegates with the following signature:
public delegate bool Predicate <T>(T obj)
- Define a way to check if an object meets some Boolean criteria
- Similar to Func<T,bool>
-
Used by many methods of Array and List<T> to search for an element
- For example List<T>.FindAll(…) retrieves all elements meeting the criteria
Predicates - Example
Action<T> and Func<T>
- Action<T> - void delegate with parameter T
- Func<T, Result> - result delegate returning Result
Action<int> act = (number) =>
{
Console.WrileLine(number);
}
act(10); // logs 10
Func<string, int, string> greet = (name, age) =>
{
return "Name: " + name + "Age: " + age;
}
Console.WriteLine(greet("Ivaylo", 10));
LINQ and Query Keywords
What is LINQ?
-
LINQ is a set of extensions to .NET Framework
- Encompasses language-integrated query, set, and transform operations
- Consistent manner to obtain and manipulate "data" in the broad sense of the term
-
Query expressions can be defined directly within the C# programming language
- Used to interact with numerous data types
- Converted to expression trees at compile time and evaluated at runtime
LINQ and Query Keywords
-
Language Integrated Query (LINQ) query keywords
- from – specifies data source and range variable
- where – filters source elements
- select – specifies the type and shape that the elements in the returned sequence
- group – groups query results according to a specified key value
- orderby – sorts query results in ascending or descending order
LINQ Query Examples
LINQ Query Examples - Nested Queries
LINQ Query Examples - Orderby
Fluid API Operations
-
.Where()
- Searches by given condition
-
.First() / .FirstOrDefault()
- Gets the first matched element
-
.Last() / .LastOrDefault()
- Gets the last matched element
-
.Select() / .Cast()
- Makes projection (conversion) to another type
-
.OrderBy() / .ThenBy() / .OrderByDescending()
- Orders a collection
Fluid API Operations
-
.Any()
- Checks if any element matches a condition
-
.All()
- Checks if all element matches a condition
-
.ToArray() / .ToList() / .AsEnumerable()
- Converts the collection type
-
.Reverse()
- Reverses a collection
LINQ Query Examples - Fluid API VS Query
Querying Arrays
-
Any kind of arrays can be used with LINQ
- Can be even an untyped array of objects
- Queries can be applied to arrays of custom objects
Book[] books = {
new Book { Title="LINQ in Action" },
new Book { Title="Extreme LINQ" } };
var titles = books
.Where(book => book.Title.Contains("Action"))
.Select(book => book.Title);
var titles = b in books
where b.Title.Contains("Action")
select b.Title;
Querying Generic Lists
-
The previous example can be adapted to work with a generic list
- List<T>, Queue<T>, Stack<T>, HashSet<T>, etc.
List<Book> books = new List<Book>() {
new Book { Title="LINQ in Action" },
new Book { Title="Extreme LINQ" } };
var titles = books
.Where(book => book.Title.Contains("Action"))
.Select(book => book.Title);
Querying Strings
-
Although System.String may not be perceived as a collection at first sight
- It actually is a collection, because it implements IEnumerable<char>
var count = "Non-letter characters in this string: 8"
.Where(c => !Char.IsLetter(c))
.Count();
var count = c in "Non-letter characters in this string: 8"
where !Char.IsLetter(c)
select c.Count();
Console.WriteLine(count); // 8
Fluid API Aggregation Methods
-
.Average()
- Calculates the average value of a collection
-
.Count()
- Counts the elements in a collection
-
.Max()
- Determines the maximum value in a collection
-
.Sum()
- Sums the values in a collection
Aggregation Methods - Examples
double[] temperatures = { 28.0, 19.5, 32.3, 33.6, 26.5, 29.7 };
var highTempCount = temperatures.Count(p => p > 30);
var highTempCount =
(from p in temperatures
where p > 30
select p).Count();
Console.WriteLine(highTempCount); // 2
Aggregation Methods - Examples
double[] temperatures = { 28.0, 19.5, 32.3, 33.6, 26.5, 29.7 };
var maxTemp = temperatures.Max();
var maxTemp =
(from p in temperatures
select p).Max();
Console.WriteLine(maxTemp); // 33.6
Questions?
[C# OOP] Extension Methods, Lambda Expressions and LINQ
By telerikacademy
[C# OOP] Extension Methods, Lambda Expressions and LINQ
- 2,092