Understanding Collection Classes, Generics, Delegates, Events and Lambda Expressions in C#, Lecture notes of Introduction to Computing

The motivation for using collection classes in .NET, the benefits of generic collections, and introduces delegates, events, and lambda expressions. It includes examples of creating and using generic collections, defining and invoking delegates, and working with events. The document also covers the use of lambda expressions with multiple parameters.

Typology: Lecture notes

2019/2020

Uploaded on 12/21/2020

wrangz
wrangz 🇻🇳

5

(1)

5 documents

1 / 43

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Session 3
Chapter 9, 10 – Collections and
Generics, Delegate, Events, and
Lambda Expression
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b

Partial preview of the text

Download Understanding Collection Classes, Generics, Delegates, Events and Lambda Expressions in C# and more Lecture notes Introduction to Computing in PDF only on Docsity!

Session 3

Chapter 9, 10 – Collections and

Generics, Delegate, Events, and

Lambda Expression

Outline

• Collection classes

• Problems of Nongeneric

• The Role of Generic Type Parameters

• The System.Collection.Generic Namespace

• Delegate types

• Understanding events

• Understanding Anonymous Methods

• Understanding Lambda Expressions

The Motivation for Collection Classes

  • (^) The array
    • (^) The most primitive container you could use to hold application data
    • (^) Basic arrays can be useful to manage small amounts of fixed-size

data

  • (^) There are many other times where you require a more flexible data structure - (^) E.g., a dynamically growing and shrinking container
  • (^) .NET base class libraries provide number of collection classes
    • (^) To dynamically resize themselves on the fly as you insert or remove

items

  • (^) Offer increased type safety and are highly optimized to process

The Motivation for Collection Classes

  • (^) A collection class can belong to one of two broad categories - (^) Nongeneric collections (primarily found in the System.Collections namespace) - (^) Generic collections (primarily found in the System.Collections.Generic namespace)
  • (^) Nongeneric collections
    • (^) Operate on System.Object types and are, therefore, loosely typed containers
  • (^) Generic collections are much more type safe
    • (^) You must specify the "type of type" they contain upon creation

Working with the ArrayList

using System;
using System.Collections;
namespaceTestCode
class MainClass
public static void Main(string[] args)
ArrayList strArray =new ArrayList();
strArray.AddRange(new string[] {"First", "Second", "Third" });
// Show number of items in ArrayList.
Console.WriteLine("This collection has { 0 }items.", strArray.Count);
Console.WriteLine();
// Add a new item and display current count.
strArray.Add( 4 ); // Nongeneric =>not typesafe.
Console.WriteLine("This collection has { 0 }items.", strArray.Count);
// Display contents.
foreach (string s in strArray)
Console.WriteLine("Entry: {0}", s);
Console.WriteLine();

The Problems of Nongeneric Collections

  • (^) First, poorly performing code
    • (^) Especially when you are manipulating numerical data
    • (^) CLR must perform a number of memory transfer operations when you store structures in any nongeneric collection class prototyped to operate on System.Objects
  • (^) Second, not type safe
    • (^) Because they were developed to operate on System.Objects
    • (^) User needs to cast to specific type to use, this might lead to wrong type casting

The System.Collections.Generic Namespace

Person.cs

public class Person
public string FirstName{get;set;}
public string LastName{get;set;}
public int Age{get;set;}
public Person()
public Person(string firstName, string lastName, int age)
FirstName=firstName;
LastName=lastName;
Age=age;
public overridestring ToString()
return string.Format("{0}{ 1 }, {2}", FirstName, LastName, Age);

Working with the Stack Class

public static void Main(string[] args) { StackstackOfPeople=new Stack(); stackOfPeople.Push(new Person {FirstName ="Homer", LastName="Simpson", Age= 47 }); stackOfPeople.Push(new Person {FirstName ="Marge", LastName ="Simpson", Age= 45 }); stackOfPeople.Push(new Person {FirstName ="Lisa", LastName="Simpson", Age= 9 }); // Now look at thetop item, pop it, and look again. Console.WriteLine("First person is: { 0 }", stackOfPeople.Peek()); Console.WriteLine("Popped off { 0 }", stackOfPeople.Pop()); Console.WriteLine("\nFirst person is: {0}", stackOfPeople.Peek()); Console.WriteLine("Popped off { 0 }", stackOfPeople.Pop()); Console.WriteLine("\nFirst person item is: { 0 }", stackOfPeople.Peek()); Console.WriteLine("Popped off { 0 }", stackOfPeople.Pop()); try { Console.WriteLine("\nnFirst person is: { 0 }", stackOfPeople.Peek()); Console.WriteLine("Popped off { 0 }", stackOfPeople.Pop()); } catch (InvalidOperationException ex) { Console.WriteLine("\nError! { 0 }", ex.Message); } }

Working with the Queue Class

static void GetCoffe e(Person p) { Console.WriteLine("{ 0 }got coffe e!", p.FirstName); } public static void Main(string[] args) { // Makea Q with threepeople. QueuepeopleQ =new Queue(); peopleQ.Enqueue(new Person {FirstName="Homer", LastName="Simpson", Age= 47 }); peopleQ.Enqueue(new Person {FirstName="Marge", LastName="Simpson", Age = 45 }); peopleQ.Enqueue(new Person {FirstName="Lisa", LastName ="Simpson", Age= 9 }); // Peek at first person in Q. Console.WriteLine("{ 0 }is first in line!", peopleQ.Peek().FirstName); // Remove each person from Q. GetCoffe e(peopleQ.Dequeue()); GetCoffe e(peopleQ.Dequeue()); GetCoffe e(peopleQ.Dequeue()); // Try to de-Q again? try { GetCoffe e(peopleQ.Dequeue()); } catch (InvalidOperationException e) { Console.WriteLine("Error! { 0 }", e.Message); } }

Working with the SortedSet Class

public static void Main(string[] args) { // Makesomepeoplewith different ages. SortedSetsetOfPeople=new SortedSet(new SortPeopleByAge()) { new Person {FirstName="Homer", LastName="Simpson", Age= 47 }, new Person {FirstName="Marge", LastName="Simpson", Age= 45 }, new Person {FirstName="Lisa", LastName="Simpson", Age= 9 }, new Person {FirstName="Bart", LastName="Simpson", Age= 8 } }; // Note theitems aresorted by age! foreach (Person p in setOfPeople) { Console.WriteLine(p); } Console.WriteLine(); // Add a few new people, with various ages. setOfPeople.Add(new Person {FirstName="Saku", LastName="J ones", Age= 1 }); setOfPeople.Add(new Person {FirstName="Mikko", LastName="J ones", Age= 32 }); // Still sorted by age! foreach (Person p in setOfPeople) { Console.WriteLine(p); } }

Working with the Dictionary<TKey, TValue> Class

public static void Main(string[] args)
// Populateusing Add() method
Dictionary<string, Person>peopleA =new Dictionary<string, Person>();
peopleA.Add("Homer", new Person {FirstName="Homer", LastName="Simpson", Age= 47 });
peopleA.Add("Marge", new Person {FirstName="Marge", LastName="Simpson", Age= 45 });
peopleA.Add("Lisa", new Person {FirstName="Lisa", LastName="Simpson", Age= 9 });
// Get Homer.
Person homer =peopleA["Homer"];
Console.WriteLine(homer);
// Populatewith initialization syntax.
Dictionary<string, Person>peopleB =new Dictionary<string, Person>()
{"Homer", new Person {FirstName="Homer", LastName="Simpson", Age= 47 }},
{"Marge", new Person {FirstName="Marge", LastName="Simpson", Age= 45 }},
{"Lisa", new Person {FirstName="Lisa", LastName="Simpson", Age= 9 }}
// Get Lisa.
Person lisa =peopleB["Lisa"];
Console.WriteLine(lisa);

Understanding the .NET Delegate Type

  • (^) Programmers use callbacks to configure one function to report back to another function in the application - (^) E.g., to handle button clicking, etc., and general bidirectional communications between two entities in memory
  • (^) A delegate
    • (^) Is a type-safe object that points to another method (or list of methods), which can be invoked at a later time
  • (^) A delegate maintains three important pieces of information
    • (^) The address of the method on which it makes calls
    • (^) The parameters (if any) of this method
    • (^) The return type (if any) of this method

Defining a Delegate Type in C#

• To create a delegate type in C#

– Use the delegate keyword

– The name can be whatever you desire

– However, you must define the delegate to match the

signature of the method(s) it will point to

• For example, the following delegate type can point

to any method that

– takes two integers as input parameters

– returns an integer

– public delegate int BinaryOp(int x, int y);