< Prev 1 2 3 4 Next >
LINQ, Language Integrated Query, is a great new feature of C# 3.0. This page gives a small overview of LINQ. Before we start with LINQ we have to understand some new features of C# 3.0 that were added so LINQ could work.
LINQ, Language Integrated Query, is a great new feature of C# 3.0. This page gives a small overview of LINQ. Before we start with LINQ we have to understand some new features of C# 3.0 that were added so LINQ could work.
- New Features in C# 3.0
- Lambda Expressions Lambda expressions are a list of inputs, the "=>" symbol, and an expression body.
We can make using delegates shorter by using a lambda expression:x => x * 0.05
When using more than one input variable, surround the input with parenthesis and separate with commas.// CalculateTax is a delegate that takes a double and returns a double public delegate double CalculateTax(double x); static void Main(string[] args) { CalculateTax stateDelegate = x => x * 0.05; CalculateTax federalDelegate = x => { if (x > 1000.0) return x * 0.02; else return 0.0; }; double amountOfPurchase = 12.99; Console.WriteLine("{0}", stateDelegate(amountOfPurchase)); Console.WriteLine("{0}", federalDelegate(amountOfPurchase)); Console.In.ReadLine(); }
Although these examples are painfully contrived, the common use of lambdas are in LINQ being used as anonyous delegates.using System; namespace PlayingAround { class Lambda { public delegate int Largest(int x, int y); public static Largest myLargest = (int x, int y) => { return x > y ? x : y; }; private static void Main() { Console.Out.WriteLine("myLargest(4,5) = " + myLargest(4,5)); //prints 5 Console.Out.Write("press return to exit."); Console.In.ReadLine(); } } }
- Passing a lambda function to a method with void return type If we want to pass a lambda function that has a void return type and a single argument we use the system "Action" delegate. What we'd really like to do is use something like "Func<string,void>", but "void" is not a valid type, so instead we must use the "Action" delegate.
using System; namespace PlayingAround { class MyAction { public static void Main() { Action<string> printMe = x => Console.Out.Write(x); Action<string> printMeAllCaps = x => Console.Out.Write(x.ToUpper()); ExecuteThreeTimes(printMe, "."); ExecuteThreeTimes(printMeAllCaps, "aBc"); //produces "...ABCABCABC" Console.Out.Write("press return to exit.");Console.In.ReadLine(); } private static void ExecuteThreeTimes(Action<string> func, string s) { func(s); func(s); func(s); } } }
- Using FuncFunctions are now a first class citizens in .Net. You can declare them with "Func". Func's take all their argument types and then their return type at the end as shown below:
using System; namespace PlayingAround { class MyFunc { public static void Main() { //this function takes a string and returns an int Func<string, int> countMe = x => { return x.Length; }; LogMeInt(countMe, "lamb"); Console.Out.Write("press return to exit.");Console.In.ReadLine(); } private static int LogMeInt(Func<string, int> func, string s) { int count = func(s); Console.Out.WriteLine("count = " + count);//in real life we'd log the results to a db or something return count; } } }
- Extension MethodsIn C#3.0 one of the very cool concepts is "Open Classes" where you can add methods to existing classes. In C# parlance this is an extension method. Below is an example of adding a new method to our old friend "string".
using System; namespace PlayingAround { public static class MyStringExtensionClass { //wraps an xml tag around a string public static string Wrap(this string s, string tag) { return "<" + tag + ">" + s + "</" + tag + ">"; } } class TestMe { static void Main(string[] args) { Console.WriteLine("Warning".Wrap("h1")); // <h1>Warning</h1> Console.In.ReadLine(); } } }
- Automatic PropertiesIn the old days before c# 3.0 you had to manually create the hidden variable behind fields:
With Automatic Properties, the compiler will generate a private field for you. You can change this later if you need to do something more elegant than just get the private field's value.using System; using System.Collections.Generic; public class Book { private string _author; private string _title; public string Author { get{return _author;} set{_author = value;} } public string Title { get{return _title;} set{_title = value;} } public static void Main() { Book myBook = new Book(); myBook.Title = "Gates of Fire"; myBook.Author = "Stephen Pressfield"; Console.In.ReadLine(); } }
using System; using System.Collections.Generic; public class Book { public string Author { get; set; } public string Title { get; set; } public static void Main() { Book myBook = new Book(); myBook.Title = "Gates of Fire"; myBook.Author = "Stephen Pressfield"; Console.WriteLine(myBook.Title); Console.In.ReadLine(); } }
- Local Variable Type InferenceThe compiler can infer the type of a variable from the expression on the right side. These are useful in LINQ expressions when the types can be overwhelming to enter, trust me. The type can be something like a function that takes a function with two ints and a float, and another function that takes a string and returns a function that takes two ints and a function that...
It is important to remember that this is not a type-less variable, the complier just infers and checks it at compile time.
var i = 6; //trivial example, not really used in practice with ints Console.Out.WriteLine("i=" + i);
- Object Initialization in C# 3.0Objects can now be initialized in a more concise manner as shown below:
... public class House { public double price; public int stories; public string exterior; } class TestMe { static void Main(string[] args) { //old style House myOldHouse = new House(); myOldHouse.price = 200000.00; myOldHouse.stories = 1; myOldHouse.exterior = "wood"; //new style House myNewHouse = new House { price = 250000.00, stories = 2, exterior = "brick" }; Console.In.ReadLine(); } }
- Anonymous TypesWe can create anonymous types. The compiler will give our creation a hidden name.
var animal = new { IsMammal = true , Name = "lion" }; Console.Out.WriteLine("Name=" + animal.Name); Console.Out.WriteLine("is mammal? " + animal.IsMammal);
- Collection InitializersInstead of the klunky:
Using the collection initializer we can writeArrayList ab = new ArrayList(); ab.Add("a"); ab.Add("b");
ArrayList ab = new ArrayList {"a", "b"};
- AggregationAggregators are extension methods that act on IEnumerable<T>
int[] ints = { 1, 3, 5, 7 }; Console.WriteLine(ints.Sum()); // 16 Console.WriteLine(ints.Min()); // 1 Console.WriteLine(ints.Max()); // 7 Console.WriteLine(ints.Average()); // 4
- Expression TreesThis is a new feature in C# 3.0, which is not used by a typical developer, but are used by creators of LINQ-enabled storage devices.
- Partial FunctionsPartial functions allow class designers to put in hooks for future use. If the functions are never given substance, the compiler ignores them.
Adding a definition for myPreHook() will cause the compiler to generate the code and it will be executed.using System; namespace PlayingAround { public partial class MyTest { partial void myPreHook();//never given substance, ignored by compiler public MyTest() { myPreHook(); Console.Out.WriteLine("Creating MyTest."); } public static void Main() { MyTest myTest = new MyTest(); Console.Out.Write("press return to exit."); Console.In.ReadLine(); } } }
public partial class MyTest { partial void myPreHook() { Console.Out.WriteLine("myPreHook."); } }
- Lambda Expressions Lambda expressions are a list of inputs, the "=>" symbol, and an expression body.
- LINQ - Language Integrated QueryLINQ is designed to work with any storage medium, e.g., SQL, XML, DataSets, or objects.
LINQ has two syntaxes: query expression which is kinda SQL-like or standard dot notation which is standard c# . I prefer the dot notation since it really shows what is happening and it works with all query operators.
Make sure you have a reference to "System.data.Linq.dll" in your solution.
Below is an example using some of the LINQ features for in-memory objects. LINQ enables VStudio to give intelliSense to some queries. For in-memory LINQ, it's all about using the Standard Query Operators. These are extension methods on the IEnumerable<T> class, methods like "Where()","Select()","Sum()" and "Average()".
- Example using Standard Query Operators This shows the use of the Where(), OrderBy(), Count(), Sum(), Min(), Select(), and ForEach() methods.
using System; using System.Collections.Generic; using System.Linq; namespace PlayingAround { internal class Photo { public Photo(string photographer, string subject, int year, double cost) { this.photographer = photographer; this.subject = subject; this.year = year; this.cost = cost; } public string photographer { get; set; } public string subject { get; set; } public int year { get; set; } public double cost { get; set; } public override string ToString() { return photographer + ", " + subject + ", " + year + ", " + cost; } } internal class PhotoLab { private static void Main(string[] args) { List<Photo> list = new List<Photo> { new Photo("Frank", "Cats", 2002, 1.10), new Photo("Lee", "Dogs and Cats", 2003, 2.05), new Photo("Sarah", "Stingrays", 2007, 23.00), new Photo("Jon", "Meerkats", 2005, 16.75) }; //simple where clause var oldPhotos = list.Where(p => p.year == 2003); Console.Out.WriteLine("oldPhotos.Count() = {0}", oldPhotos.Count()); // 1 //Order Operators //use OrderBy extension operator to sort oldPhotos = list.OrderBy(p => p.year); //2002, 2003, 2005, 2007 foreach (var photo in oldPhotos) { Console.Out.WriteLine("photo = {0}", photo); } oldPhotos = list.OrderByDescending(p => p.year); //2007, 2005, 2003, 2002 foreach (var photo in oldPhotos) { Console.Out.WriteLine("photo = {0}", photo); } //Aggregate Operators var number = list.Count(p => p.year > 2003); //sums the length of all the photographer's names. Did I mention this is a contrived example? number = list.Sum(p => p.photographer.Length); Console.Out.WriteLine("number = {0}", number); //16 //find shortest subject length number = list.Min(p => p.subject.Length); Console.Out.WriteLine("number = {0}", number); //4 //using "Select" to create new anonymous classes var photos = list.Where(p => p.year < 2005).Select(p => new {p.photographer, p.year}); foreach (var photo in photos) { Console.Out.WriteLine("photo = {0}", photo); //photo = { photographer = Frank, year = 2002 }... } //write all photos to console list.ForEach(p => Console.WriteLine(p)); //same as above but more concise, and a little spooky list.ForEach(Console.WriteLine); Console.In.ReadLine(); } } }
- Create your own LINQ Query Operators Below is an example of extending the IEnumerable<T> class to include an operator that returns a List<T> of every other item.
using System; using System.Collections.Generic; namespace PlayingAround { class EveryOtherExample { private static void Main() { List<int> ints = new List<int>{0, 1, 2, 3, 4, 5, 6}; ints.ForEach(i => Console.Out.Write(i)); List<int> everyOther = ints.EveryOther(); //call our new Query Operator everyOther.ForEach(i => Console.Out.Write(i));// writes 0246 Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } // let's create our own (non)Standard Query Operator /// <summary> /// returns every other item starting with the first item /// </summary> public static class MyEveryOtherExtensionMethod { public static List<T> EveryOther<T>(this IEnumerable<T> source) { List<T> list = new List<T>(); bool shouldIAddIt = true; foreach (var variable in source) { if(shouldIAddIt) {list.Add(variable);} //add every other one shouldIAddIt = !shouldIAddIt; } return list; } } }
- Deferred QueriesMany of the standard query operators do not execute immediately, but wait until needed. In the example below "abc.Intersect(cdef)" is not executed until needed for printing. It is re-evaluted when needed again.
using System; using System.Collections; using System.Collections.Generic; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { class Deferred { private static void Main() { List<string> abc = new List<string> { "a", "b", "c" }; List<string> cdef = new List<string> { "c","d","e","f"}; IEnumerable intersection = abc.Intersect(cdef); //deferred execution cdef[3] = "a"; foreach (var letter in intersection) //now the IEnumerable intersection is done { Console.Out.WriteLine("letter = " + letter); //writes a,c } cdef[2] = "b"; //Getting the Enumerator for "intersection" forces it to start to reconstruct the list again foreach (var letter in intersection) { Console.Out.WriteLine("letter = " + letter); //writes a,b,c } Console.Out.Write("press return to exit."); Console.In.ReadLine(); } } }
- Explicit InterfacesSometimes different interfaces have the same method signatures. To specify a specific interface, preface the method with the name of the interface followed by a ".". When calling the method, the object must be cast as that interface type.
using System; namespace PlayingAround { class ExplicitInterface { interface IFlute { void Play(); } interface IGuitar { void Play(); } class Musician : IFlute, IGuitar { void IFlute.Play() { Console.WriteLine("Playing Flute"); } void IGuitar.Play() { Console.WriteLine("Playing Guitar"); } } public static void Main(string[] args) { Console.WriteLine("hello"); Musician muscian = new Musician(); //muscian.Play(); error //with Explicit Interfaces you must declare which interface is being called ((IFlute)muscian).Play(); Console.ReadLine(); } } }
- Creating an Xml document with Linq(namespace omitted for clarity)
Produces:using System; using System.Xml.Linq; namespace PlayingAround { /// <summary> /// creates an xml document with nested elements /// </summary> class XmlCreate { private static void Main() { XElement books = new XElement("books", new XElement("book", new XAttribute("title","Peopleware"), new XElement("author","DeMarco and Lister")), new XElement("book", new XAttribute("title", "Agile and Iterative Development"), new XElement("author", "Craig Larman"))); Console.Out.WriteLine("books.ToString() = \r\n" + books); Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- Using LINQ to search xml filesWe use "var" as the type of "demarco_books" becasue the real type reported by "GetType()" is quite a mouthful, "demarco_books.GetType() = System.Linq.Enumerable+<WhereIterator>d__0`1[System.Xml.Linq.XElement]
Given this xml fileusing System; using System.IO; using System.Linq; using System.Xml.Linq; namespace PlayingAround { class LinqXml { private static void Main() { XElement books = XElement.Parse(File.ReadAllText(@"..\..\books.xml")); IEnumerable<XElement> demarco_books = books.Elements("book").Where(book => book.Element("author").ToString().Contains("DeMarco")); demarco_books.ToList().ForEach(b => Console.Out.WriteLine("DeMarco books: " + b.Attribute("title"))); Console.Out.Write("done."); Console.In.ReadLine(); } } }
The program produces:<books> <book title="Peopleware"> <author>DeMarco and Lister</author> </book> <book title="Agile and Iterative Development"> <author>Craig Larman</author> </book> <book title="Design Patterns"> <author>Gamma, Helm, Johnson, Blissides</author> </book> <book title="Software Creativity 2.0"> <author>Robert L Glass and Tom DeMarco</author> </book> </books>
DeMarco books: title="Peopleware" DeMarco books: title="Software Creativity 2.0" done.
- Using LINQ to sort objects
using System; using System.Linq; namespace PlayingAround { class LinqArray { private static void Main() { string[] presidents = {"Washington", "Madison", "Lincoln"}; //let's sort the array var sorted = presidents.OrderBy(p => p); sorted.ToList().ForEach(p => Console.Out.WriteLine(p)); Console.Out.Write("press return to exit."); Console.In.ReadLine(); } } }
- Using Legacy Collections C# offers a few ways to use older collections like ArrayList with LINQ. Cast() will try to cast all elements to the desired generic type. In the example below Cast() is successful in casting "12" to a string, so the number of elements is 5. OfType() will pluck out of the original Arraylist all the correct types, so its count is only 4. If we uncomment the line adding "new object()", which cannot be cast to a string, the Cast() method will throw an InvalidCastException, but the OfType() method will just ignore it.
Some people will recommend using OfType() because it will not throw an exception when encountering an unexpected type of object. I usually prefer Cast() because I want to know up front during testing if any odd type has wandered into my collection. The only time to use OfType() is when you really expect to find mixed object types in your collection.
using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace PlayingAround { class Legacy { private static void Main() { ArrayList arrayList = new ArrayList(); arrayList.Add("up"); arrayList.Add("down"); arrayList.Add("charm"); arrayList.Add("strange"); arrayList.Add(12); //arrayList.Add(new object()); //will cause exception in Cast() IEnumerable<string> quarks = arrayList.Cast<string>().OrderByDescending(q => q); Console.Out.WriteLine("Number of elements = " + quarks.Count()); //5 quarks = arrayList.OfType<string>().OrderByDescending(q => q); Console.Out.WriteLine("Number of elements = " + quarks.Count()); //4 Console.Out.Write("press return to exit."); Console.In.ReadLine(); } } }
- ProjectionProjection takes a series of one type of object and creates a series of another type.
using System; using System.Collections.Generic; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { public class Book { public string author; public string title; public string rating; } class Projection { private static void Main() { List<Book> books = new List<Book> { new Book {author = "Demarco", title = "PeopleWare", rating = "Good"}, new Book {author="Tolkien", title="The Hobbit", rating="Super"}, new Book {author="Pressfield", title="Gates of Fire", rating="Super"} }; //authorAndTitle has some machine-generated mangled type name var authorAndTitle = books.Select(b => new {b.author, b.title}); //projection authorAndTitle.ToList().ForEach(Console.WriteLine); /* prints: { author = Demarco, title = PeopleWare } { author = Tolkien, title = The Hobbit } { author = Pressfield, title = Gates of Fire } */ Console.Out.WriteLine("authorAndTitle type = " + authorAndTitle.GetType()); /* prints "authorAndTitle type = System.Linq.Enumerable+<SelectIterator>d__d`2[PlayingAround.Book,<>f__AnonymousType1`2[System.String,System.String]]" */ Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- Partioning Functions Take(), TakeWhile(), Skip(), and SkipWhile()
using System; using System.Collections.Generic; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { class TakeWhile { private static void Main() { int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8}; //Take simply returns the first n elements IEnumerable<int> three = numbers.Take(3); three.ToList().ForEach(n => Console.Write(n)); //writes: 012 //TakeWhile returns elements until one of them is false and then stops IEnumerable<int> odds = numbers.TakeWhile(n => n < 5); odds.ToList().ForEach(n => Console.Write(n)); //writes: 01234 IEnumerable<int> skipFive = numbers.Skip(5); //skips first five skipFive.ToList().ForEach(n => Console.Write(n)); //writes: 5678 Console.WriteLine(); IEnumerable<int> skipWhileLessThanFour = numbers.SkipWhile(n => n < 4); skipWhileLessThanFour.ToList().ForEach(n => Console.Write(n)); //writes: 45678 Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- Concatenationthe Concat() method joins lists
using System; using System.Collections; using System.Collections.Generic; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { class Concat { private static void Main() { int[] little = { 0, 1, 2, 3, 4 }; int[] big = { 5, 6, 7, 8 }; IEnumerable<int> all = little.Concat(big); all.ToList().ForEach(n => Console.Write(n)); //writes: 012345678 Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- SortingOrderBy(),ThenBy()
Produces:using System; using System.Collections; using System.Collections.Generic; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { class Order { public class Employee { public string last; public string first; public double salary; public Employee(string last, string first, double salary) { this.last = last; this.first = first; this.salary = salary; } override public string ToString() {return string.Format("{0}, {1}: ${2}", last, first, salary);}} public static void Main() { Employee[] employees = { new Employee("Jones", "Sara", 11000.00), new Employee("Jones", "Brad", 10000.00), new Employee("Aaron", "Mike", 10000.00), new Employee("Xader", "Xena", 20000.00) }; Print("No ordering", employees); Print("Order by last", employees.OrderBy(n => n.last)); Print("Order by last, first",employees.OrderBy(n => n.last).ThenBy(n => n.first)); Print("order by salary", employees.OrderBy(n => n.salary)); Print("order by salary descending", employees.OrderByDescending(n => n.salary)); Console.Out.Write("press return to exit.");Console.In.ReadLine(); } static void Print(string title, IEnumerable<Employee> objects) { Console.WriteLine(title+":"); objects.ToList().ForEach(n => Console.WriteLine(n)); } } }
- Set OperatorsLINQ provides Union, Intersect, Distinct, and Except.
using System; using System.Collections.Generic; using System.Linq; namespace PlayingAround { class Sets { private static void Main() { int[] little = {0, 1, 2, 3, 4, 5, 6}; int[] big = {5, 6, 7, 8, 9, 10}; IEnumerable<int> all = little.Union(big); all.ToList().ForEach(n => Console.Write(n)); //writes 012345678910 Console.WriteLine(); IEnumerable<int> intersect = little.Intersect(big); intersect.ToList().ForEach(n => Console.Write(n)); //writes 56 Console.WriteLine(); IEnumerable<int> both = little.Concat(big); both.ToList().ForEach(n => Console.Write(n)); //writes 01234565678910 Console.WriteLine(); IEnumerable<int> dist = both.Distinct(); dist.ToList().ForEach(n => Console.Write(n)); //writes 012345678910 Console.WriteLine(); //"Except()" returns all elements of the first sequence that do not exist in the second IEnumerable<int> exceptional = little.Except(big); exceptional.ToList().ForEach(n => Console.Write(n)); //writes 01234 Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- Helper functionsRange, Reverse, Repeat, and Empty
using System; using System.Collections.Generic; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { class Range { private static void Main() { //note: Range. Empty and Repeat are not extension methods, but static ones IEnumerable<int> one2five = Enumerable.Range(1, 5); one2five.ToList().ForEach(n => Console.Write(n)); //writes: 12345 IEnumerable<int> five2one = one2five.Reverse(); five2one.ToList().ForEach(n => Console.Write(n)); //writes: 54321 IEnumerable<int> fivethrees = Enumerable.Repeat(3,5); fivethrees.ToList().ForEach(n => Console.Write(n)); //writes: 33333 //Empty creates an empty Enumerable of the specific type IEnumerable<int> empty = Enumerable.Empty<int>(); fivethrees.ToList().ForEach(n => Console.Write(n)); //writes: Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- NonDeferred Conversion MethodsToArray, ToList, ToDictionary, and ToLookup
using System; using System.Collections.Generic; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { public class BookItem { public string author; public string title; public string rating; } class NonDeferred { private static void Main() { List<BookItem> books = new List<BookItem> { new BookItem {author = "Demarco", title = "PeopleWare", rating = "Good"}, new BookItem {author= "Tolkien", title= "The Hobbit", rating = "Super"}, new BookItem {author= "Pressfield", title = "Gates of Fire", rating = "Super"} }; //convert to an array BookItem[] bookItems = books.ToArray(); //convert to list List<BookItem> bookList = books.ToList(); //now, finally something interesting, the dictionary, (one key to one object) Dictionary<string, BookItem> dict = books.ToDictionary(b => b.author); Console.Out.WriteLine(dict["Tolkien"].title); //writes: The Hobbit //now for something even more interesting, a Lookup (one key, many objects) ILookup<string, BookItem> bookLookup = books.ToLookup(b => b.rating); IEnumerable<BookItem> superBooks = bookLookup["Super"]; foreach (var book in superBooks) { Console.WriteLine("A super book is "+book.title); //writes: The Hobbit, Gates of Fire } Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- Grabbing an item and searching for items
using System; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { class NonDeferred2 { private static void Main() { string[] names = {"Cindy", "Bobby", "Jan", "Peter", "Marcia", "Greg"}; bool eq = names.SequenceEqual(names.Reverse().Reverse()); //returns true // -- Finding an item //First grabs the first item Console.WriteLine(names.First()); //writes: "Cindy" Console.WriteLine(names.First(p => p.StartsWith("J"))); //writes: "Jan" Console.WriteLine(names.Last()); //writes: "Greg" //selects the last item that matches a function Console.WriteLine(names.Last(p => p.Length>4)); //writes: "Marcia" Console.WriteLine(names.LastOrDefault(p => p.Length > 8)); //writes: // -- Seaching for items //Single returns the only element of a sequence, or throws an exception try { Console.WriteLine(names.Single()); //throws InvalidOperationException: } catch(InvalidOperationException) { Console.WriteLine("I was expecting only one element"); } //with a predicate it returns the only one, or throws an exception Console.WriteLine(names.Single(p=>p.StartsWith("B"))); //writes: "Bobby" //ElementAt selects the element at that index (zero based) Console.WriteLine(names.ElementAt(2)); //writes: "Jan" //Any() returns true if the sequence has any elements Console.WriteLine(names.Any()); //writes: "true" //Any(p) return true if any element matches the predicate Console.WriteLine(names.Any(p => p.Length>3)); //writes: "true" //All(p) returns true only if all the elements match the condition Console.WriteLine(names.All(p => p.Length > 4)); //writes: "false" //Contains returns true if that object is in the sequence Console.WriteLine(names.Contains("Carol")); //writes: "false" Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- Common math functions Count, Sum, Min, Max, and Average
using System; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { class Maths { private static void Main() { int[] fibs = {0, 1, 1, 2, 3, 5, 8}; Console.WriteLine(fibs.Count()); //writes: 7 Console.WriteLine(fibs.Count(p => p < 3)); //writes: 4 Console.WriteLine(fibs.Sum()); //writes: 20 Console.WriteLine(fibs.Min()); //writes: 0 Console.WriteLine(fibs.Max()); //writes: 8 Console.WriteLine(fibs.Average()); //writes: 2.85714285714286 Console.Out.Write("press return to exit.");Console.In.ReadLine(); } } }
- Aggregate, the "Reduce" function in LINQ
using System; using System.Linq; //need this to get creamy goodness of IEnumerable<T> extension methods namespace PlayingAround { class Aggregate { private static void Main() { int[] numbers = {1, 2, 3, 4, 5, 6}; //Aggregate performs a function on each of the elements and carries the result //forward to the next element (Called a "Reduce" operation) int sumOfSquares = numbers.Aggregate(0, (sum,n) => n*n + sum); Console.Out.WriteLine("sumOfSquares = " + sumOfSquares); //writes: 91 //concatenate all the strings together string allwords = words.Aggregate("", (temp, word) => temp + word); Console.Out.WriteLine("allwords = {0}", allwords); //writes: onetwothree Console.ReadKey(); } } }
< Prev 1 2 3 4 Next >
- Example using Standard Query Operators This shows the use of the Where(), OrderBy(), Count(), Sum(), Min(), Select(), and ForEach() methods.
No comments:
Post a Comment