Object Oriented Programming Web forms, web controls and ASP.NET Dr. Mike Spann [email protected].
Object Oriented Programming Generic Collections and LINQ Dr. Mike Spann [email protected].
-
Upload
andra-green -
Category
Documents
-
view
230 -
download
0
Transcript of Object Oriented Programming Generic Collections and LINQ Dr. Mike Spann [email protected].
Object Oriented Programming
Generic Collections and Generic Collections and LINQLINQ
Dr. Mike SpannDr. Mike Spann
[email protected]@bham.ac.uk
Contents
Introduction to collection objects and LINQIntroduction to collection objects and LINQ Querying an arrayQuerying an array Generic collectionsGeneric collections Querying a generic collectionQuerying a generic collection LINQ to XMLLINQ to XML SummarySummary
Introduction to collection objects and LINQ .NET provides a set of pre-packaged data structures .NET provides a set of pre-packaged data structures
known as collectionsknown as collections They have been carefully designed to ensure They have been carefully designed to ensure
robust and efficient performancerobust and efficient performance ArrayArray
Efficient random access but inefficient to resize Efficient random access but inefficient to resize itit
ListListEnables dynamic resizing but not random accessEnables dynamic resizing but not random access
Introduction to collection objects and LINQ
In addition, C# provides a mechanism for In addition, C# provides a mechanism for querying collections known as LINQquerying collections known as LINQ Language Integrated QueryLanguage Integrated Query
LINQ enables access to collections (and LINQ enables access to collections (and databases!) using databases!) using query expressions query expressions which which are similar to SQL queriesare similar to SQL queries This allows the retrieval of information This allows the retrieval of information
from a wide variety of data sourcesfrom a wide variety of data sources
Introduction to collection objects and LINQ
We will primarily look at We will primarily look at LINQ to ObjectsLINQ to Objects Enables the querying on collection objectsEnables the querying on collection objects
.NET also provides LINQ providers for :.NET also provides LINQ providers for : LINQ to SQLLINQ to SQL
For querying databasesFor querying databases LINQ to XMLLINQ to XML
For querying xml documentsFor querying xml documents
Querying an array
We can design a simple LINQ query which filters We can design a simple LINQ query which filters the contents of an arraythe contents of an array Applying the query to the array causes all the Applying the query to the array causes all the
values of the array which meet a certain criteria values of the array which meet a certain criteria to be extractedto be extracted
But the query doesn’t say But the query doesn’t say howhow the iteration the iteration through the array is performed through the array is performed All the necessary code is generated by the All the necessary code is generated by the
compiler, the query just specifies the criteriacompiler, the query just specifies the criteria
Querying an array
A simple query object comprises A simple query object comprises from, where from, where and and selectselect clauses clauses Also, we can make use of the keyword Also, we can make use of the keyword var var which is an which is an
implicit typeimplicit typeEssentially a strongly typed local variable but the type is Essentially a strongly typed local variable but the type is
determined by the compilerdetermined by the compiler
In this case the type of the array is determined by the data In this case the type of the array is determined by the data source typesource type
var filteredArray =from ...... // range variable and data sourcewhere ..... // boolean expressionselect..... // which value appears in the results
using System;using System.Collections.Generic;using System.Linq;
class LINQtoArray{ static void Main(string[] args) { int[] array = { 2, 6, 4, 12, 7, 8, 9, 13, 2 };
var filteredArray = // LINQ query from element in array where element < 7 select element;
PrintArray(filteredArray, "All values less than 7:"); }
public static void PrintArray(IEnumerable<int> arr, string message) { Console.Write("{0}",message);
foreach (var element in arr) Console.Write(" {0}", element);
Console.WriteLine(); }}
Querying an array
IEnumerable<T> IEnumerable<T> is an interface is an interface implemented by arrays and collectionsimplemented by arrays and collections
It is a It is a generic typegeneric type We replace the We replace the TT by a real type (such as by a real type (such as
an an intint)) More on this laterMore on this later
Querying an array
We can add the We can add the orderbyorderby (descending) (descending) clause to our query to sort our filtered array clause to our query to sort our filtered array into ascending (descending) orderinto ascending (descending) order
var filteredArray =from ...... // range variable and data sourcewhere ..... // boolean expression
orderby ..... (descending) // sortselect..... // which value appears in the results
using System;using System.Collections.Generic;using System.Linq;
class LINQtoArray{ static void Main(string[] args) { int[] array = { 2, 6, 4, 12, 7, 8, 9, 13, 2 };
var filteredArray = // LINQ query from element in array where element < 7 select element;
PrintArray(filteredArray, "All values less than 7:");
var orderedFilteredArray = from element in filteredArray orderby element select element;
PrintArray(orderedFilteredArray, "All values less than 7 and sorted:"); }
public static void PrintArray(IEnumerable<int> arr, string message) {……}}
Querying an array
It's important to understand a feature of LINQ known as It's important to understand a feature of LINQ known as deferred executiondeferred execution The result of a LINQ query expression The result of a LINQ query expression is notis not a sequence or a sequence or
collection of objects but a collection of objects but a query objectquery object It represents the commands needed to execute the query It represents the commands needed to execute the query The query The query does not execute until the program requests data does not execute until the program requests data
from the query objectfrom the query object Deferred execution is a powerful feature of LINQ as it Deferred execution is a powerful feature of LINQ as it
allows applications to pass queries around as dataallows applications to pass queries around as data In our simple example, the query is not run until it is In our simple example, the query is not run until it is
passed to the passed to the PrintArray PrintArray methodmethod
Querying an array We can use LINQ to query an array of user defined objects or We can use LINQ to query an array of user defined objects or
stringsstrings We must be careful when using We must be careful when using orderbyorderby
The objects must be comparableThe objects must be comparable Comparable types in .NET implement the Comparable types in .NET implement the IComparable<T> IComparable<T>
interfaceinterface Built in primitive types automatically implement Built in primitive types automatically implement
IComparable<T>IComparable<T>The ‘The ‘TT’’ is a parameterised typeis a parameterised typeWe will look at these in more detail laterWe will look at these in more detail later
For example we can query an array of For example we can query an array of StudentInfoStudentInfo objects objects
class StudentInfo{ public StudentInfo(string ln, string fn, int id, string a) { lastName = ln; firstName = fn; idNumber = id; address = a; }
public override string ToString() { return firstName+" "+lastName+" "+idNumber+" " +address; }
public string FirstName { get { return firstName; }
}
public string LastName { get { return lastName; } }
public string Address { get { return address; } }
public int ID { get { return idNumber; }
}
private string firstName,lastName;private int idNumber;
private string address;}
Querying an array
We can filter the array by ID numberWe can filter the array by ID number Simply get the ID property of the range Simply get the ID property of the range
variablevariable Also we can sort the names into last name Also we can sort the names into last name
order and then first name order using order and then first name order using orderbyorderby This uses the fact that the This uses the fact that the stringstring type type
implements implements IComparable<T>IComparable<T>
public class LINQtoObjectArray{ static void Main(string[] args) { StudentInfo[] students ={ new StudentInfo("Smith", "John", 12345, "5 Bournbrook Rd"), new StudentInfo("Brown", "Alan", 23412, "Dawlish Rd"), new StudentInfo("Smith","Colin", 41253, "23 Bristol Rd"), new StudentInfo("Hughes", "Richard", 52314, "18 Prichatts Rd"), new StudentInfo("Murphy", "Paul", 16352, "37 College Rd") };
// Filter a range of ID numbers var idRange= from s in students where s.ID>19999 && s.ID<=49999 select s;
PrintArray(idRange,"Students with ID in Range 2000 to 4999");
// Order by last name and then first name var nameSorted = from s in students orderby s.LastName, s.FirstName select s;
PrintArray(nameSorted, "Students sorted in last name, first name order");
}
public static void PrintArray<T>(IEnumerable<T> arr, string message) {…}}
Querying an array
Querying an array
We can use LINQ to sort the array of We can use LINQ to sort the array of StudentInfoStudentInfo objects by implementing the objects by implementing the IComparableIComparable interface interface We simply need to implement the We simply need to implement the
CompareTo()CompareTo() method method If this isn’t done when we try and sort an If this isn’t done when we try and sort an
array of objects using LINQ, a runtime array of objects using LINQ, a runtime exception is generatedexception is generated
Querying an array
class StudentInfo : IComparable{ public StudentInfo(string ln, string fn, int id, string a) { lastName = ln; firstName = fn; idNumber = id; address = a; }
public int CompareTo(object obj) { StudentInfo s = (StudentInfo)obj;
if (s.ID < ID) return 1; else if (s.ID > ID) return -1; else return 0; }
.
.
. .
private string firstName,lastName;private int idNumber;
private string address;}
Querying an array
public class LINQtoObjectArray{ static void Main(string[] args) { StudentInfo[] students ={ new StudentInfo("Smith", "John", 12345, "5 Bournbrook Rd"), new StudentInfo("Brown", "Alan", 23412, "Dawlish Rd"), new StudentInfo("Smith","Colin", 41253, "23 Bristol Rd"), new StudentInfo("Hughes", "Richard", 52314, "18 Prichatts Rd"), new StudentInfo("Murphy", "Paul", 16352, "37 College Rd") };
// Order by ID var IDSorted = from s in students orderby s select s;
PrintArray(IDSorted, "Students sorted in ID order");
public static void PrintArray<T>(IEnumerable<T> arr, string message) {…}
}}
Querying an array
Querying an array LINQ defines a number of extension methods of LINQ defines a number of extension methods of IEnumerable<T>IEnumerable<T>
Extension methods extend the functionality of Extension methods extend the functionality of existingexisting classes classes (including classes in the FCL)(including classes in the FCL)
Any()Any()
• Checks to see if the container has any membersChecks to see if the container has any members Count()Count()
• Returns a count of the number of membersReturns a count of the number of members First(), Last()First(), Last()
• Returns the first and last members of the containerReturns the first and last members of the container Distinct()Distinct()
• Removes duplicate membersRemoves duplicate members
public class LINQtoObjectArray{ static void Main(string[] args) { StudentInfo[] students ={ new StudentInfo("Smith", "John", 12345, "5 Bournbrook Rd"), new StudentInfo("Brown", "Alan", 23412, "Dawlish Rd"), new StudentInfo("Smith","Colin", 41253, "23 Bristol Rd"), new StudentInfo("Hughes", "Richard", 52314, "18 Prichatts Rd"), new StudentInfo("Murphy", "Paul", 16352, "37 College Rd") };
// Order by last name and then first name var nameSorted = from s in students orderby s.LastName, s.FirstName select s;
PrintArray(nameSorted, "Students sorted in last name, first name order");
Console.WriteLine("There are " + students.Count() + " students");
if (nameSorted.Any()) { Console.WriteLine("First in list " +
nameSorted.First().ToString());
Console.WriteLine("Last in list " + nameSorted.Last().ToString());
} }}
Querying an array
Generic collections In our example programs so far we have already seen a In our example programs so far we have already seen a generic generic
method PrintArray<T>method PrintArray<T> This function outputs the string representation of the This function outputs the string representation of the
elements of an arrayelements of an array Its full declarations is :Its full declarations is :
PrintArray<T> PrintArray<T> takes any type which implements the takes any type which implements the IEnumerable<T> IEnumerable<T> interfaceinterface
Thus an Thus an IEnumerable IEnumerable object of any type can be passed to object of any type can be passed to the methodthe method
public static void PrintArray<T>(IEnumerable<T> arr ,string message)
Generic collections
The compiler infers the type The compiler infers the type TT from the from the actual call to actual call to PrintArray<T>PrintArray<T>
public class LINQtoObjectArray{ static void Main(string[] args) { StudentInfo[] students ={………}; // Order by last name and then first name var nameSorted = from s in students orderby s.LastName, s.FirstName select s;
// PrintArray<StudentInfo> called here
PrintArray(nameSorted, "Students sorted in last name, first name order");
.
. }}
Generic collections
Also the compiler determines whether the Also the compiler determines whether the operations in the method body can be operations in the method body can be performed on any type the performed on any type the TT represents represents
class MyClass{ public static void PrintArray(IEnumerable<int> arr, string message) { Console.Write("{0}",message);
// Requires a ToString() override method for non built in types foreach (var element in arr) Console.Write(" {0}", element);
Console.WriteLine(); }}
Generic collections
Collections store groups of objectsCollections store groups of objects We are all familiar with arraysWe are all familiar with arrays
Arrays don’t resize dynamically but do so when the Arrays don’t resize dynamically but do so when the Resize()Resize() method is called method is called
The collection class The collection class List<T> List<T> dynamically resizes when dynamically resizes when objects are insertedobjects are inserted It’s known as a generic class because real classes are It’s known as a generic class because real classes are
instantiated by providing actual types in place of instantiated by providing actual types in place of TTList<int>, List<string>, List<StudentInfo> etcList<int>, List<string>, List<StudentInfo> etc
Generic collectionsMethod or property
Description
Add Adds an element to the end of the List
Capacity Property that gets or sets the number of elements a Listcan store
Clear Removes all the elements from the List
Contains Returns true if the List contains the specified element;otherwise, returns false
Count Property that returns the number of elements stored in theList
IndexOf Returns the index of the first occurrence of the specifiedvalue in the List
Insert Inserts an element at the specified index
Remove Removes the first occurrence of the specified value
RemoveAt Removes the element at the specified index
RemoveRange Removes a specified number of elements starting at aspecified index
Sort Sorts the List
TrimExcess Sets the Capacity of the List to the number of elementsthe List currently contains (Count)
Generic collections
We can create a list of We can create a list of StudentInfoStudentInfo objects objects and add items (to the end of the list) and and add items (to the end of the list) and insert items (anywhere in the list)insert items (anywhere in the list)
We can display the list using exactly the We can display the list using exactly the same generic function as for displaying an same generic function as for displaying an arrayarray
We could manipulate the list using the We could manipulate the list using the methods shown in the tablemethods shown in the table
public class LINQtoList{ static void Main(string[] args) {
StudentInfo[] students ={ new StudentInfo("Smith", "John", 12345, "5 Bournbrook Rd"), new StudentInfo("Brown", "Alan", 23412, “Dawlish Rd"), new StudentInfo("Smith","Colin", 41253, "23 Bristol Rd"), new StudentInfo("Hughes", "Richard", 52314, "18 Prichatts Rd"), new StudentInfo("Murphy", "Paul", 16352, "37 College Rd") }; List<StudentInfo> studentList = new List<StudentInfo>();
studentList.Add(students[0]); studentList.Add(students[1]); studentList.Add(students[2]);
studentList.Insert(2, students[3]);
PrintList(studentList, "Student list:"); }
public static void PrintList<T>(IEnumerable<T> arr, string message) { Console.WriteLine("{0}", message);
foreach (T element in arr) Console.WriteLine(" {0}", element);
Console.WriteLine(); }}
Generic collections
Querying a generic collection
LINQ to Objects can query lists (and any other LINQ to Objects can query lists (and any other collection) in much the same way as querying an collection) in much the same way as querying an arrayarray
For example, we could sort our list of students after For example, we could sort our list of students after first converting their surnames into upper casefirst converting their surnames into upper case The query makes use of the The query makes use of the letlet clause which clause which
creates a new range variablecreates a new range variable Enables a temporary result to be stored for later Enables a temporary result to be stored for later
use in the queryuse in the query
public class LINQtoList{ static void Main(string[] args) {
StudentInfo[] students ={ new StudentInfo("Smith", "John", 12345, "5 Bournbrook Rd"), new StudentInfo("Brown", "Alan", 23412, “Dawlish Rd"), new StudentInfo("Smith","Colin", 41253, "23 Bristol Rd"), new StudentInfo("Hughes", "Richard", 52314, "18 Prichatts Rd"), new StudentInfo("Murphy", "Paul", 16352, "37 College Rd") }; List<StudentInfo> studentList = new List<StudentInfo>();
studentList.Add(students[0]); studentList.Add(students[1]); studentList.Add(students[2]);
studentList.Insert(2, students[3]);
var orderedUpperCaseList = from student in studentList let upperCaseName = student.LastName.ToUpper() orderby upperCaseName select upperCaseName;
PrintList(orderedUpperCaseList, "Ordered student list:"); }
public static void PrintList<T>(IEnumerable<T> arr, string message) {…}}
Querying a generic collection
LINQ to XML
XML (Extensible Markup Language) is a widely supported XML (Extensible Markup Language) is a widely supported standard for describing virtually any kind of information standard for describing virtually any kind of information data data
It is a used primarily to describe data which is shared It is a used primarily to describe data which is shared between applications across a networkbetween applications across a network
It comprises It comprises elementselements delineated by a start and end tag and delineated by a start and end tag and data data
XML files are simple text files with no formatting structureXML files are simple text files with no formatting structure LINQ contains a number of classes for parsing and LINQ contains a number of classes for parsing and
manipulating XML filesmanipulating XML files
LINQ to XML
A simple XML document can describe A simple XML document can describe student information datastudent information data
<?xml version = "1.0"?><!-- Student information data structured with XML -->
<studentInfo><name> John Smith </name>
<birthday> February 21 1987 </birthday>
<courseInfo><code> 45235 </code><courseTitle> Electrical Engineering </courseTitle><degree> MEng </degree>
</courseInfo>
<address> 21 Bristol Road </address>
</studentInfo>
LINQ to XML
XML documents can be stored as a tree structure in XML documents can be stored as a tree structure in memorymemory Known as a Known as a Document Object Model (DOM) Document Object Model (DOM) tree tree
Each element in the XML document is Each element in the XML document is represented by a tree node represented by a tree node
XML parsers can create such a tree from the XML parsers can create such a tree from the XML fileXML file
The tree can then be manipulated The tree can then be manipulated programmatically by high level languagesprogrammatically by high level languages
LINQ to XML
studentInfo
name
birthday
courseInfo
address
code
courseTitle
degree
LINQ to XML
Namespace Namespace System.Xml.LinqSystem.Xml.Linq contains classes used to contains classes used to manipulate a DOMmanipulate a DOM XDocumentXDocument represents an entire XML document represents an entire XML document XElementXElement represents a tree node represents a tree node
XElement.Name XElement.Name propertyproperty allows the name of allows the name of the node element to be get or set (including the node element to be get or set (including namespace)namespace)
XElement.Name.LocalNameXElement.Name.LocalName is the name is the name without the namespace prefixwithout the namespace prefix
LINQ to XML
We can write a simple program which uses these We can write a simple program which uses these classes to read in our XML document and display classes to read in our XML document and display individual elementsindividual elements Uses the Uses the HasElements HasElements property to determine if an property to determine if an
XElement XElement object has children and object has children and Elements()Elements() method to obtain the childrenmethod to obtain the children
Uses the Uses the ValueValue property to return text associated property to return text associated with an with an XElement XElement object (for object (for XElement XElement objects objects with no children)with no children)
using System;using System.Collections.Generic;using System.Linq;using System.Xml.Linq;
public class LINQtoXML{ public static void Main(string[] args) { XDocument doc = XDocument.Load(“StudentInfo.xml”); PrintElement(doc.Root, 0); }
private static void PrintElement(XElement element, int indentLevel) { string name = element.Name.LocalName; Indent(indentLevel); Console.WriteLine('<' + name + '>');
if (element.HasElements) foreach (var child in element.Elements()) PrintElement(child,indentLevel+1); else { Indent(indentLevel+1); Console.WriteLine(element.Value.Trim()); } Indent(indentLevel); Console.WriteLine("</" + name + '>'); }
private static void Indent(int level) { for (int i = 0; i < level; i++) Console.Write(" "); }}
LINQ to XML
LINQ to XML
We can use LINQ to query an XML file in We can use LINQ to query an XML file in order to select specific elements or order to select specific elements or properties of elementsproperties of elements
For example we can extract an element and For example we can extract an element and all it’s descendants using the all it’s descendants using the Descendants()Descendants() methodmethod We can then iterate through each of these We can then iterate through each of these
using the using the Elements()Elements() method method
LINQ to XML
public class LINQtoXML{ public static void Main(string[] args) { XDocument doc = XDocument.Load("StudentInfo.xml");
// Select a specific element var elements = from el in doc.Descendants("courseInfo") select el;
foreach (var e in elements) PrintElement(e, 0);
Console.WriteLine();
var elements1 = from e2 in doc.Descendants("courseInfo").Elements() where e2.Name.LocalName.StartsWith("c") select e2;
foreach (var e in elements1) PrintElement(e, 0); }
private static void PrintElement(XElement element, int indentLevel){....}
}
LINQ to XML
Summary
We have looked at querying simple arrays using We have looked at querying simple arrays using LINQLINQ
We have looked at extension methods and how We have looked at extension methods and how they are incorporated into LINQthey are incorporated into LINQ
We have looked at generic lists and how we query We have looked at generic lists and how we query them using LINQthem using LINQ
We have looked at LINQ to XML and how we can We have looked at LINQ to XML and how we can query XML files using LINQquery XML files using LINQ