About Me

Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

Fun With Linq and C# 3.0
Using TransactionScope in .Net 2.0 To Test Your Mapping Layer
VS 2005 Compilation Woes
And So It Begins

Archive

Blogroll

 Agile Developer Venkat's Blog
 Ayende @ Blog
 B#
 Barry Gervin's Software Architecture Perspectives
 Boy Meets World
 Brad Abrams
 Canadian Developers
 Christopher Steen
 Claritude Software News
 Clemens Vasters: Enterprise Development and Alien Abductions
 Coding Horror
 Coding in an Igloo
 Dare Obasanjo aka Carnage4Life
 Darrell Norton's Blog [MVP]
 David Hayden [MVP C#]
 Don Box's Spoutlet
 Eric Gunnerson's C# Compendium
 EZWeb guy: Jeffrey Palermo [C# MVP]
 Fear and Loathing
 Generalities & Details: Adventures in the High-tech Underbelly
 Greg Young [MVP]
 Greg's Cool [Insert Clever Name] of the Day
 IanG on Tap
 Ingo Rammer's Weblog
 ISerializable - Roy Osherove's Blog
 James Kovacs' Weblog
 Jason Haley
 Jean-Luc David
 Jeremy D. Miller -- The Shade Tree Developer
 JetBrains .NET Tools Blog
 Jimmy Nilsson's weblog
 John Bristowe's Weblog
 John Papa [MVP C#]
 Jon Skeet's Coding Blog
 JonGalloway.ToString()
 Jump the Fence or Walk Around
 Lambda the Ultimate - Programming Languages Weblog
 Larkware News
 Lutz Roeder
 Marquee de Sells: Chris's insight outlet
 Martin Fowler's Bliki
 Mike Nichols - SonOfNun Technology
 MSDN Magazine - .NET Matters
 MSDN Magazine - All Articles
 OdeToCode Blogs
 Onion Blog
 Planet TW
 Raymond Lewallen [MVP]
 Rockford Lhotka
 RodMan's Corner
 Roger Johansson's blog
 Sahil Malik - blah.winsmarts.com
 Sam Gentile's Blog
 Scott Bellware [MVP]
 Scott Hanselman's Computer Zen
 ScottGu's Blog
 secretGeek
 Service Station, by Aaron Skonnard
 Signum sine tinnitu--by Guy Kawasaki
 Stephen Toub
 Steve Eichert's Blog
 Steven Rockarts
 The Blog Ride
 The Coding Hillbilly
 The Daily WTF
 TheServerSide.net: News
 Tim Gifford
 Vance Morrison's Weblog
 you've been HAACKED

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 397
This Year: 122
This Month: 0
This Week: 0
Comments: 1033

 Thursday, December 15, 2005
Thursday, December 15, 2005 8:36:03 AM (Mountain Standard Time, UTC-07:00) ( .Net 3.0 | C# )
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:

  • Extension Classes
  • Lambda Expressions
  • Language Integrated Query(LINQ)


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:


1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Query;
5 using System.Xml.XLinq;
6 using System.Data.DLinq;
7 using NUnit.Framework;
8 using LinqMadness.Core;
9 using System.Query;
10 namespace LinqMadness.Test
11 {
12 [TestFixture]
13 public class StringExtensionTest
14 {
15 [Test]
16 public void ShouldBeAbleToReverseString()
17 {
18 Assert.AreEqual("tsaoT","Toast".Reverse());
19 }
20
21 [Test]
22 public void ShouldBeAbleToTestForPalindrome()
23 {
24 Assert.IsTrue("pop".IsPalindrome());
25 Assert.IsTrue("barcrab".IsPalindrome());
26 Assert.IsTrue("elbertandednatreble".IsPalindrome());
27 Assert.IsFalse("nonPalindrome".IsPalindrome());
28 }
29
30
31 }
32 }
As you can see from the above test class, using extension classes I have been able to dynamically add methods to any instance of a string object. How did he do that?? Look at the following code that shows how this is accomplished:

1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Query;
5 using System.Xml.XLinq;
6 using System.Data.DLinq;
7 8 namespace LinqMadness.Core
9 {
10 public static class StringExtensions
11 {
12 public static string Reverse(this string stringToReverse)
13 {
14 StringBuilder builder = new StringBuilder(stringToReverse.Length);
15 for(int i = stringToReverse.Length-1;i>=0;i--)
16 {
17 builder.Append(stringToReverse[i]);
18 }
19 return builder.ToString();
20 }
21
22 public static bool IsPalindrome(this string toCheck)
23 {
24 25 for(int i = 0;i < toCheck.Length/2;i++)
26 {
27 if (toCheck[i] != toCheck[toCheck.Length -1 -i])
28 {
29 return false;
30 }
31 return true;
32 }
33 34 }
35 }



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:

public static string Reverse(this string stringToReverse)

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 Linq technical preview.
Comments [0] | | # 
 Tuesday, December 13, 2005
Tuesday, December 13, 2005 8:34:35 AM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 )
How many times have you found yourself writing code to cleanup changes that your mapping tests make to the database. Save yourself some time and make use of the new TransactionScope class in .Net 2.0.

Take a look at the following code fragment to see a good pattern for use. The class makes use of the NUnit 2.2.3 testing framework.

1 [TestFixture]
2 public class SomeMapperTest
3 {
4 TransactionScope scope;
5 6 [SetUp]
7 public void SetUp()
8 {
9 scope = new TransactionScope();
10 }
11
12 [Test]
13 public void ShouldBeAbleToInsertDomainObjectToDatabase()
14 {
15 using(scope)
16 {
17 TestDatabaseGateway gateway = new TestDatabaseGateway();
18 int existingRowsInTargetTable = gateway.GetRowCountFor("TargetTable");
19 SomeDomainObject objectToPersist = new SomeDomainObject();
20 SomeMapper mapper = new SomeMapper();
21 mapper.Insert(objectToPersist);
22 Assert.AreEqual(existingRowsInTargetTable+1,
23 gateway.GetRowCountForTable(“TargetTable”));
24 }
25 }
26 27 }
Comments [1] | | # 
Tuesday, December 13, 2005 8:33:10 AM (Mountain Standard Time, UTC-07:00) ( VS2005 )
Is it just me or has the speed at which VS2005 compiles applications slowed down dramatically?

When it was in the beta versions I just shrugged it off as being an issue that would be worked on and inevitable fixed by the release version of the product. Several months into a current engagement has proven that the release build of studio has done nothing at all to increase the speed at which the IDE is able to compile.

The team that I currently work on utlizes an agile development process. We write some tests, implement some code, get the tests passing and carry on. Were it not for automated build tools (thank you NAnt) this process would be painstakingly slow.

Now granted, compile speed is relative based on the size of the project right? Fair enough. Needless to say that comparitively sized projects took measurably less time to compile in previous versions of Visual Studio.

Just something to watch out for as you see that solution explorer scrollbar increasing in size!!
Comments [0] | | # 
 Sunday, December 04, 2005
Sunday, December 04, 2005 8:08:26 AM (Mountain Standard Time, UTC-07:00) ( )
Well, I finally joined the blogosphere! Consider this blog as an outlet for me to share my thoughts, opinions, and suggestions about some of the following topics : * Enterprise Development With .Net * Test Driven Development * Domain Driven Design * The Trials and Tribulations of Working With Visual Studio I have to speak quickly to the last point. Over the course of my development career I have, for the most part, spent most of my time in the Microsoft world. And yet I am considered, by many, to have viewpoints that are very contrary to the typical Microsoft viewpoints on application development. I have made it one of my personal missions to share information that is definitely not common place in the MS world right now. Information that I feel can help developers reach a new level of enjoyment and satisfaction while coding using Microsoft technologies, in particular with the .Net Framework. So who am I that I feel I can speak about these things? I am a Senior Developer with ThoughtWorks where I am involved daily with the development of complex enterprise scale applications. I have presented several MSDN webchats on the topics of application development with the .Net Framework, and have been actively working with .Net since beta 1 of 1.0. Stay tuned, lots of great information to follow.
Comments [0] | | # 
<