As you already may know, Microsoft released the preview of Linq a while ago, to give developers a chance to play with some of the language features that are going to be in C# 3.0. Some of the new features that will be introduced are:
So what does all this mean to you as a developer? Here is an example of what can be accomplished with extension classes. How many times have you found yourself writing some sort of StringUtility class in your applications? Would'nt it be nice if you could just add methods that all instances of string would be able to call? Well with C# 3.0 it looks like this:
A couple of key points to note here. Notice the use of a static class. More importantly look at the signature of one of the methods that extends string with new functionality:
The use of the this keyword coupled with the type argument to the method indicates that this method is a behaviour that now will belong to all string instances.
Ok, so as cool as that is, take a look at the following code that demonstrates some of the new LINQ features in C# 3.0.
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using NUnit.Framework;
5 using System.Query;
6
7 namespace LinqMadness.Test
8 {
9 [TestFixture]
10 public class CollectionTest
11 {
12 [Test]
13 public void ShouldBeAbleToFindAllOddNumbersInList()
14 {
15 List<int> numbers = new List<int>();
16 numbers.Add(1);
17 numbers.Add(2);
18 numbers.Add(3);
19 numbers.Add(4);
20 numbers.Add(5);
21
22 Assert.AreEqual(3,numbers.FindAll(i => (i % 2) != 0).Count);
23 Assert.AreEqual(1,numbers.Min());
24 }
25
26 [Test]
27 public void ShouldBeAbleToCreateCustomType()
28 {
29 IList<Customer> customers = new List<Customer>(){newCustomer("JP","555-4444",23,"SomeAddress","Canada"),
30 new Customer("Aaron","555-4444",23,"SomeAddress","Canada")};
31
32 foreach (Customer customer in customers)
33 {
34 var customerDTO = new{customer.CustomerName, customer.Phone};
35 Assert.AreEqual(customer.CustomerName,customerDTO.CustomerName);
36 Assert.AreEqual(customer.Phone,customerDTO.Phone);
37 }
38 }
39
40 [Test]
41 public void ShouldBeAbleToUseQuerySyntax()
42 {
43 IList<Customer> customers = new List<Customer>(){new Customer("JP","555-4444",27,"SomeAddress","Canada"),
44 new Customer("APerson1","555-4444",27,"SomeAddress","Canada"),
45 new Customer("APerson2","555-4444",8,"SomeAddress","Canada"),
46 new Customer("APerson3","555-4444",6,"SomeAddress","Canada"),
47 new Customer("APerson4","555-4444",3,"SomeAddress","Canada"),
48 new Customer("APerson5","555-4444",1,"SomeAddress","Canada")};
49
50
51 IEnumerable<Customer> customersOver8 = from c in customers
52 where c.Age > 8
53 select c;
54
55 IEnumerable<Customer> customersBeginningWithA = from c in customers
56 where c.CustomerName.StartsWith("A")
57 select c;
58
59
60 IEnumerable<Customer> customersWithOddNameLength = from c in customers
61 where c.CustomerName.Length % 2 != 0
62 select c;
63
64 Assert.AreEqual(2,new List<Customer>(customersOver8).Count);
65 Assert.AreEqual(2,new List<Customer>(customersBeginningWithA).Count);
66 Assert.AreEqual(1,new List<Customer>(customersWithOddNameLength).Count);
67
68 }
69
70 [Test]
71 public void ShouldBeAbleToMultiplyUsingFold()
72 {
73 List<int> numbers = new List<int>{1,2,3,4,5,6,7};
74 int product = numbers.Fold((start,current)=> start * current);
75 Assert.AreEqual(5040,product);
76 }
77
78 [Test]
79 public void ShouldBeAbleToSum()
80 {
81 List<int> numbers = new List<int>{1,2,3,4,5,6,7};
82 int sum = numbers.Sum();
83 Assert.AreEqual(28,sum);
84 }
85
86 [Test]
87 public void ShouldBeAbleToSeeIfListsAreEqual()
88 {
89 Assert.IsTrue(new List<int>(){1,2,3}.EqualAll(new List<int>(){1,2,3}));
90 Assert.IsFalse(new List<int>(){1,2,3}.EqualAll(new List<int>(){1,2,4}));
91 }
92
93 [Test]
94 public void ShouldBeAbleToGetDistinct()
95 {
96 Assert.AreEqual(4,new List<int>(new int[]{1,2,2,3,3,4}.Distinct()).Count);
97 }
98
99
100 [Test]
101 public void ShouldBeAbleToUnionTwoSets()
102 {
103 List<int> firstSet = new List<int>(){1, 2, 3, 2, 2, 2, 4, 5};
104 List<int> secondSet = new List<int>(){4, 5, 2, 2, 3, 4, 6, 7};
105
106 Assert.AreEqual(7,new List<int>(firstSet.Union(secondSet)).Count);
107 }
108
109
110 [Test]
111 public void ShouldBeAbleToIntersectTwoSets()
112 {
113 List<int> firstSet = new List<int>(){1,2,3,3,4,5,6,7};
114 List<int> secondSet = new List<int>(){4,8,9};
115
116 Assert.AreEqual(1,new List<int>(firstSet.Intersect(secondSet)).Count);
117 }
118
119 [Test]
120 public void ShouldBeAbleToOutputSquares()
121 {
122 int numberToSquare = 0;
123 foreach (int square in Sequence.Range(1,30).Select(i => i * i))
124 {
125 numberToSquare++;
126 Assert.AreEqual(numberToSquare * numberToSquare,square);
127 }
128 }
129
130 private class Customer
131 {
132 private string customerName;
133 private string phone;
134 private int age;
135 private string address;
136 private string country;
137
138
139 public Customer(string customerName, string phone, int age, string address,string country)
140 {
141 this.customerName = customerName;
142 this.phone = phone;
143 this.age = age;
144 this.address = address;
145 this.country = country;
146 }
147
148
149 public string CustomerName
150 {
151 get { return customerName; }
152 }
153
154 public string Phone
155 {
156 get { return phone; }
157 }
158
159 public int Age
160 {
161 get { return age; }
162 }
163
164 public string Address
165 {
166 get { return address; }
167 }
168
169
170 public string Country
171 {
172 get { return country; }
173 }
174 }
175 }
176 }
I'll let you wrap your head around that one over the weekend and will dive more into the details of how it all works in a later post. If you want to be able to run the code, you will need to download and install the
technical preview.