<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1641640765672872979</id><updated>2011-07-28T15:35:02.005-07:00</updated><category term='Moq'/><category term='tdd'/><category term='testing'/><category term='timer'/><category term='mocking'/><category term='generics'/><category term='extension methods'/><title type='text'>Talking Code</title><subtitle type='html'>Talk about ideas and code samples that come up in my daily routine as a developer.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thorstenlorenz.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://thorstenlorenz.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Thorsten Lorenz</name><uri>http://www.blogger.com/profile/11869165877618370852</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://2.bp.blogspot.com/_zO4YPCT1Z1Y/Sl8i1KY8CAI/AAAAAAAAAJQ/8gdBLNXtJtU/S220/keep.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1641640765672872979.post-5152385112989986438</id><published>2009-07-01T13:21:00.000-07:00</published><updated>2009-07-02T06:40:57.300-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='timer'/><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='Moq'/><title type='text'>Mocking a timer</title><content type='html'>Most of us in the testing world are probably familiar with the following problem:&lt;br /&gt;&lt;br /&gt;We want to test, that once we call a method, it will start a timer which will then invoke another method when the interval elapsed.&lt;br /&gt;&lt;br /&gt;A very simple test, that just deals with the System Timer itself could look like this:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;var mockTimer = new System.Timers.Timer(1);&lt;br /&gt;&lt;br /&gt;bool elapsedFired = false;&lt;br /&gt;mockTimer.Elapsed += (sender, e) =&gt; elapsedFired = true;&lt;br /&gt;mockTimer.Start();&lt;br /&gt;&lt;br /&gt;Assert.That(elapsedFired);&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;Although we told it to fire after only 1ms, this test will fail (at least most times) because the &lt;code&gt;Assert&lt;/code&gt; will be examined before the timer fired - all thanks to our fast technologies.&lt;br /&gt;One remedy would be to make sure we wait long enough so the timer has a chance to fire by adding: &lt;code class="prettyprint"&gt; System.Threading.Thread.Sleep(200); &lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The revised test looks like this:&lt;br /&gt;&lt;pre class="prettyprint"&gt;var mockTimer = new System.Timers.Timer(1);&lt;br /&gt;&lt;br /&gt;bool elapsedFired = false;&lt;br /&gt;mockTimer.Elapsed += (sender, e) =&gt; elapsedFired = true;&lt;br /&gt;mockTimer.Start();&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;System.Threading.Thread.Sleep(200);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Assert.That(elapsedFired);&lt;br /&gt;&lt;/pre&gt;It will now pass. So problem solved? Not at all, just found a questionable workaround.&lt;br /&gt;This solution is bad for two reasons.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The test could still fail whenever the timer thread is much slower than the one we are on.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If we have a lot of tests like that, they will take a very long time, which needs to be avoided.&lt;/li&gt;&lt;/ol&gt;Today though I was faced exactly with this problem.&lt;br /&gt;At first I tried to mock the timer using Moq, to at least verify, that the timer.Start() method got called. Unfortunately for unknown reasons Moq will claim, that it didn't get called at all even though I called it inside the test. So this doesn't seem to work.&lt;br /&gt;Additionally, I would like to check, that the registered methods get invoked, when the Elapsed Event fires.&lt;br /&gt;So I tried another route.&lt;br /&gt;&lt;br /&gt;I created a class &lt;code&gt;FireOnStartTimer&lt;/code&gt; that inherits from&lt;code&gt; System.Timers.Timer&lt;/code&gt; in which I tried to trigger the Elapsed event by hand, right when the timer is started, like so:&lt;br /&gt;&lt;pre class="prettyprint"&gt;public new void Start()&lt;br /&gt;{&lt;br /&gt;this.Elapsed.Invoke(this, new EventArgs() as System.Timers.ElapsedEventArgs);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Notice that I couldn't override the &lt;code&gt;Start()&lt;/code&gt; method, therefore I used &lt;code&gt; new void Start()&lt;/code&gt; instead.&lt;br /&gt;&lt;br /&gt;The compiler didn't like that solution though and gave me this error:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The event 'System.Timers.Timer.Elapsed' can only appear on the left hand side of += or -= (CS0079)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What to do?&lt;br /&gt;I decided to "new" the Elapsed Eventhandler itself as well, hoping that since then my class "owns" it, I would be allowed to do what I tried previously.&lt;br /&gt;I added:&lt;code class="prettyprint"&gt;&lt;br /&gt;public new event System.Timers.ElapsedEventHandler Elapsed;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Bingo!  Now it compiled!&lt;br /&gt;&lt;br /&gt;I ran the previous test, without the ugly &lt;code class="prettyprint"&gt;System.Threading.Thread.Sleep(200);&lt;span style="font-family:Georgia,serif;"&gt;: &lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var mockTimer = new FireOnStartTimer();&lt;br /&gt;&lt;br /&gt;bool elapsedFired = false;&lt;br /&gt;mockTimer.Elapsed += (sender, e) =&gt; elapsedFired = true;&lt;br /&gt;mockTimer.Start();&lt;br /&gt;&lt;br /&gt;Assert.That(elapsedFired);&lt;br /&gt;&lt;/pre&gt;&lt;code class="prettyprint"&gt;&lt;span style="font-family:Georgia,serif;"&gt;&lt;/span&gt;&lt;/code&gt;And it passed still.&lt;br /&gt;&lt;br /&gt;Mission accomplished!&lt;br /&gt;&lt;br /&gt;Here is the complete FireOnStartTimer class:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class FireOnStartTimer : System.Timers.Timer&lt;br /&gt;{&lt;br /&gt;public new event System.Timers.ElapsedEventHandler Elapsed;&lt;br /&gt;&lt;br /&gt;public FireOnStartTimer() : base() {}&lt;br /&gt;public FireOnStartTimer(double interval, ISynchronizeInvoke syncObject)&lt;br /&gt;: this()&lt;br /&gt;{&lt;br /&gt;this.SynchronizingObject = syncObject;&lt;br /&gt;this.AutoReset = false;&lt;br /&gt;this.Enabled = true;&lt;br /&gt;this.Interval = interval;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public new void Start()&lt;br /&gt;{&lt;br /&gt;this.Elapsed.Invoke(this, new EventArgs() as System.Timers.ElapsedEventArgs);&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;For convenience I have added a Constructor which sets up the timer for me, this is not required though, so this would be the essence of an hour of experimentation:&lt;br /&gt;&lt;pre class="prettyprint"&gt;class FireOnStartTimer : System.Timers.Timer&lt;br /&gt;{&lt;br /&gt;public new event System.Timers.ElapsedEventHandler Elapsed;&lt;br /&gt;&lt;br /&gt;public new void Start()&lt;br /&gt;{&lt;br /&gt;this.Elapsed.Invoke(this, new EventArgs() as System.Timers.ElapsedEventArgs);&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Tiny but of great use.&lt;br /&gt;&lt;br /&gt;Finally I needed to create a Timer interface and an adapter for the &lt;code&gt;System.Timers.Timer&lt;/code&gt; that implements the interface.&lt;br /&gt;It is necessary to pass the timer into the system under test as &lt;code&gt;ITimer&lt;/code&gt; in order to make use of polymorphism and in that way ensure that the &lt;code&gt;Start()&lt;/code&gt; method of our custom timer is called during testing. If we would just pass it in as &lt;code&gt;System.Timers.Timer&lt;/code&gt;, our Custom  &lt;code&gt;Start()&lt;/code&gt; method is never invoked, but instead the one of &lt;code&gt;System.Timers.Timer&lt;/code&gt;. Also we want to avoid any &lt;code class="prettyprint"&gt;&lt;br /&gt;if (myTimer is FireOnStartTimer)&lt;br /&gt;(myTimer as FireOnStartTimer).Start();&lt;br /&gt;else&lt;br /&gt;  (myTimer a&lt;span style="font-family:monospace;"&gt;s&lt;/span&gt;&lt;code&gt; System.Timers.Timer&lt;/code&gt;).Start(); &lt;/code&gt;&lt;br /&gt;kind of mess.&lt;br /&gt;&lt;br /&gt;Since  both Timer classes implement the &lt;code&gt;ITimer&lt;/code&gt; interface, we can pass in our custom Timer during testing and the Adapter for the &lt;code&gt;System.Timers.Timer&lt;/code&gt; in the production code, without having to change the class we are testing.&lt;br /&gt;&lt;br /&gt;Here is that interface:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;public interface ITimer&lt;br /&gt;{&lt;br /&gt;void Start();&lt;br /&gt;void Stop();&lt;br /&gt;void Close();&lt;br /&gt;&lt;br /&gt;bool AutoReset { get; set; }&lt;br /&gt;bool Enabled { get; set; }&lt;br /&gt;double Interval { get; set; }&lt;br /&gt;ISynchronizeInvoke SynchronizingObject { get; set; }&lt;br /&gt;&lt;br /&gt;event ElapsedEventHandler Elapsed;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and the adapter:&lt;br /&gt;&lt;pre class="prettyprint"&gt;/// &lt;summary&gt;&amp;lt;summary&amp;gt;&lt;br /&gt;/// Adapts the System.Timers.Timer class to implement the ITimer interface.&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;public class SystemTimerAdapter : Timer, ITimer&lt;br /&gt;{&lt;br /&gt; public SystemTimerAdapter() : base() {}&lt;br /&gt; public SystemTimerAdapter(double interval) : base(interval) {}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of course other timers could also be used with above interface. All we need to do is write an adapter for them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641640765672872979-5152385112989986438?l=thorstenlorenz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thorstenlorenz.blogspot.com/feeds/5152385112989986438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thorstenlorenz.blogspot.com/2009/07/mocking-timer.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default/5152385112989986438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default/5152385112989986438'/><link rel='alternate' type='text/html' href='http://thorstenlorenz.blogspot.com/2009/07/mocking-timer.html' title='Mocking a timer'/><author><name>Thorsten Lorenz</name><uri>http://www.blogger.com/profile/11869165877618370852</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://2.bp.blogspot.com/_zO4YPCT1Z1Y/Sl8i1KY8CAI/AAAAAAAAAJQ/8gdBLNXtJtU/S220/keep.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641640765672872979.post-4431842160464786230</id><published>2009-06-27T07:47:00.000-07:00</published><updated>2009-07-03T07:42:26.857-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>Revised Generic class ToString() Method</title><content type='html'>After reading this great &lt;a href="http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html"&gt;blog&lt;/a&gt; by Rinat Abdullin, I decided to revise my &lt;a href="http://thorstenlorenz.blogspot.com/2009/06/more-extensions-generic-tostring-method.html"&gt;Generic ToString solution&lt;/a&gt; somewhat.&lt;br /&gt;&lt;br /&gt;Here is the complete class:&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// Creates a string of this format: MemberType MemberName=MemberValue&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// Usage:&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;code&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;///     string testMember = "testing";&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;///     Console.WriteLine(Member.State(() =&amp;gt; testMember));&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;/code&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// Writes  ' string testMember="testing" ' to the Console.&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Member&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; State&amp;lt;T&amp;gt;(Func&amp;lt;T&amp;gt; expr)&lt;br /&gt;    {&lt;br /&gt;        var member = ExtractMemberFromLambdaExpression(expr);&lt;br /&gt;       &lt;br /&gt;        Type memberType = GetTypeOfMember(member);&lt;br /&gt;       &lt;br /&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; contents = ExtractContentsFromLambdaExpression(expr);&lt;br /&gt;       &lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"{0} {1}={2}"&lt;/span&gt;,memberType.Name,  member.Name, contents);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ExtractContentsFromLambdaExpression&amp;lt;T&amp;gt;(Func&amp;lt;T&amp;gt; expr)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (expr() == &lt;span class="kwrd"&gt;null&lt;/span&gt;) {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"NULL"&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;       &lt;br /&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; contents = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (expr().GetType().IsArray) {&lt;br /&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; (expr() &lt;span class="kwrd"&gt;as&lt;/span&gt; Array)) {&lt;br /&gt;                contents += item.ToStringNullSafe() + &lt;span class="str"&gt;", "&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;            contents = contents.Trim().TrimEnd(&lt;span class="str"&gt;','&lt;/span&gt;);&lt;br /&gt;        } &lt;span class="kwrd"&gt;else&lt;/span&gt; {&lt;br /&gt;            contents = expr().ToString();&lt;br /&gt;        }&lt;br /&gt;       &lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; contents;&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; MemberInfo ExtractMemberFromLambdaExpression&amp;lt;T&amp;gt;(Func&amp;lt;T&amp;gt; expr)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="rem"&gt;// get IL code behind the delegate&lt;/span&gt;&lt;br /&gt;        var il = expr.Method.GetMethodBody().GetILAsByteArray();&lt;br /&gt;        &lt;span class="rem"&gt;// bytes 2-6 represent the member handle&lt;/span&gt;&lt;br /&gt;        var memberHandle = BitConverter.ToInt32(il, 2);&lt;br /&gt;        &lt;span class="rem"&gt;// resolve the handle&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; expr.Target.GetType().Module.ResolveMember(memberHandle);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; Type GetTypeOfMember(MemberInfo member)&lt;br /&gt;    {&lt;br /&gt;        Type memberType;&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (member.MemberType == MemberTypes.Field) {&lt;br /&gt;            memberType = GetFieldType(member &lt;span class="kwrd"&gt;as&lt;/span&gt; FieldInfo);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (member.MemberType == MemberTypes.Property) {&lt;br /&gt;            memberType = GetPropertyType(member &lt;span class="kwrd"&gt;as&lt;/span&gt; PropertyInfo);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt; {&lt;br /&gt;            memberType = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;object&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; memberType;&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; Type GetFieldType(FieldInfo fieldInfo)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; fieldInfo.FieldType;&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; Type GetPropertyType(PropertyInfo propertyInfo)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; propertyInfo.PropertyType;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;As you can see from the supplied example in the XML documentation header, the &lt;code&gt;&lt;/code&gt;use has become much simpler.&lt;br /&gt;It is now using Lambda expressions in order to return its values.&lt;br /&gt;&lt;br /&gt;This method uses strongly-typed reflection on the passed in lambda expression in order to obtain type and name of the field and invokes the &lt;code&gt;ToStringNullSafe()&lt;/code&gt; method on the expression itself in order to obtain the value from the field.&lt;br /&gt;&lt;br /&gt;In case you are wondering about the &lt;code&gt; ToStringNullSafe()&lt;/code&gt; method - I created these in my &lt;a href="http://thorstenlorenz.blogspot.com/2009/06/getting-it-on-with-extension-methods.html"&gt;previous blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Fortunately using the new &lt;code&gt;Member.State()&lt;/code&gt; method is a lot easier than understanding the details, but I encourage you to read &lt;a href="http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html"&gt;Rinat Abdullin's blog&lt;/a&gt; if you want to find out more. All I needed to know in order to implement this improved version, I found in there.&lt;br /&gt;&lt;br /&gt;The big advantage of this new solution compared to the &lt;a href="http://thorstenlorenz.blogspot.com/2009/06/more-extensions-generic-tostring-method.html"&gt;previous one&lt;/a&gt;, is, that now we don't have to implement an interface nor worry about the order of declaration of our member variables.&lt;br /&gt;Additionally, they don't even have to be member variables. The new solution works for almost any object that implements a &lt;code&gt;ToString()&lt;/code&gt; method.&lt;br /&gt;&lt;br /&gt;As you can see from the &lt;code&gt;ExtractContentsFromLambdaExpression &lt;/code&gt; method, if it encounters an array, it will return the contents of each value in the array.&lt;br /&gt;It will not however return anything useful when it encounters a collection that is not an array, or any object, that doesn't implement a meaningful &lt;code&gt;ToString()&lt;/code&gt; method. So think about what you pass into it.&lt;br /&gt;&lt;br /&gt;Here a short example of how to use it to print information about a class:&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PrintMyInfo&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; infoString;&lt;br /&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; counter;&lt;br /&gt;    &lt;span class="kwrd"&gt;double&lt;/span&gt;[] arrayOfValues;&lt;br /&gt;    List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; lstString;&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; PrintMyInfo()&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.infoString = &lt;span class="str"&gt;"Info"&lt;/span&gt;;&lt;br /&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.counter = 12;&lt;br /&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.arrayOfValues = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt;[] { 0.3, 0.5, 23.2};&lt;br /&gt;        lstString = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;br /&gt;        lstString.Add(&lt;span class="str"&gt;"item1"&lt;/span&gt;);&lt;br /&gt;        lstString.Add(&lt;span class="str"&gt;"item2"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToString()&lt;br /&gt;    {&lt;br /&gt;        var sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt;        sb.AppendLine(&lt;span class="str"&gt;"PrintMyInfo: "&lt;/span&gt;);&lt;br /&gt;        sb.AppendLine(Member.State(() =&amp;gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.infoString));&lt;br /&gt;        sb.AppendLine(Member.State(() =&amp;gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.arrayOfValues));&lt;br /&gt;        sb.AppendLine(Member.State(() =&amp;gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.counter));&lt;br /&gt;        sb.AppendLine(Member.State(() =&amp;gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.lstString.ToArray()));&lt;br /&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; sb.ToString();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Note how we need to copy the List to an array in order to get meaningful output.&lt;br /&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;Console.WriteLine(&lt;span class="kwrd"&gt;new&lt;/span&gt; PrintMyInfo().ToString());&lt;/pre&gt; produces the following output:&lt;br /&gt;&lt;blockquote&gt;PrintMyInfo:&lt;br /&gt;String infoString=Info&lt;br /&gt;Double[] arrayOfValues=0.3, 0.5, 23.2&lt;br /&gt;Int32 counter=12&lt;br /&gt;List`1 lstString=item1, item2&lt;/blockquote&gt;Should we ever need to change any variable names in our class, the refactoring tool, will adjust our &lt;code&gt;ToString()&lt;/code&gt; method automatically, since nothing is hardcoded in a string except the class name.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641640765672872979-4431842160464786230?l=thorstenlorenz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thorstenlorenz.blogspot.com/feeds/4431842160464786230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thorstenlorenz.blogspot.com/2009/06/after-reading-this-great-blog-by-rinat.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default/4431842160464786230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default/4431842160464786230'/><link rel='alternate' type='text/html' href='http://thorstenlorenz.blogspot.com/2009/06/after-reading-this-great-blog-by-rinat.html' title='Revised Generic class ToString() Method'/><author><name>Thorsten Lorenz</name><uri>http://www.blogger.com/profile/11869165877618370852</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://2.bp.blogspot.com/_zO4YPCT1Z1Y/Sl8i1KY8CAI/AAAAAAAAAJQ/8gdBLNXtJtU/S220/keep.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641640765672872979.post-4358735847271522483</id><published>2009-06-26T07:25:00.000-07:00</published><updated>2009-07-02T05:39:21.394-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='extension methods'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>More Extensions - The Generic ToString() Method for classes and structs</title><content type='html'>NOTE: The following solution has been improved a lot in this &lt;a href="http://thorstenlorenz.blogspot.com/2009/06/after-reading-this-great-blog-by-rinat.html"&gt;blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Don't you hate repetitive tasks?&lt;br /&gt;&lt;br /&gt;I sure do.&lt;br /&gt;Writing ToString() methods for classes is one of them.&lt;br /&gt;We will implement the same kind of ToString() methods if we need them to give us information about the object state as is very usefull when running UnitTests or logging exceptions.&lt;br /&gt;&lt;br /&gt;Here is a typical example:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class ControlData&lt;br /&gt;{&lt;br /&gt;public Point location;&lt;br /&gt;public Size size;&lt;br /&gt;&lt;br /&gt;public ControlData(Point location, Size size)&lt;br /&gt;{&lt;br /&gt;this.location = location;&lt;br /&gt;this.size = size;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public override string ToString()&lt;br /&gt;{&lt;br /&gt;return string.Format("[ControlData: {0} location={1} size={2}]", this.location, this.size);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Granted, codegenerators will do this job for you.&lt;br /&gt;But what if you want to rename some fields or the class itself.&lt;br /&gt;In that case you have to generate the ToString() method all over again, since the rename refactoring will not change anything inside of  strings.&lt;br /&gt;In our case, were we to change 'location' to 'firstLocation' its name in here:&lt;br /&gt;&lt;pre class="prettyprint"&gt;"[ControlData: {0} location={1} size={2}]"&lt;/pre&gt;&lt;br /&gt;will not change with it.&lt;br /&gt;&lt;br /&gt;Turns out, that there is a way to automate a ToString() execution alltogether. So without any further ado:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;public static string FieldsToString&amp;lt;T&amp;gt;(this T fieldContainer) where T : IFieldsEnumerable&lt;br /&gt;{&lt;br /&gt;var sb = new StringBuilder();&lt;br /&gt;int fieldCount = 0;&lt;br /&gt;&lt;br /&gt;sb.AppendFormat("[{0}:", fieldContainer.GetType().Name);&lt;br /&gt;&lt;br /&gt;foreach (var field in fieldContainer.GetFieldEnumerator())&lt;br /&gt;{&lt;br /&gt;sb.AppendFormat("\n  {0}\t{1}\t{2} ",&lt;br /&gt;           fieldContainer.GetType().GetFields()[fieldCount].FieldType.Name,&lt;br /&gt;           fieldContainer.GetType().GetFields()[fieldCount].Name,&lt;br /&gt;           field.ToString());&lt;br /&gt;fieldCount++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sb.Append("]");&lt;br /&gt;&lt;br /&gt;return sb.ToString();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now lets look at the previous class again, except that it now implements the &lt;code&gt; IFieldsEnumerable&lt;/code&gt; interface:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class ControlData : IFieldsEnumerable&lt;br /&gt;{&lt;br /&gt;public Point location;&lt;br /&gt;public Size size;&lt;br /&gt;&lt;br /&gt;public ControlData(Point location, Size size)&lt;br /&gt;{&lt;br /&gt;this.location = location;&lt;br /&gt;this.size = size;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public override string ToString()&lt;br /&gt;{&lt;br /&gt;return this.FieldsToString();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IEnumerable&amp;lt;object&amp;gt;GetFieldEnumerator()&lt;br /&gt;{&lt;br /&gt;yield return location;&lt;br /&gt;yield return size;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is that interface:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;public interface IFieldsEnumerable&lt;br /&gt;{&lt;br /&gt;IEnumerable&amp;lt;object&amp;gt;GetFieldEnumerator();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Calling:&lt;br /&gt;&lt;pre class="prettyprint"&gt;new ControlData(new Point(12, 13), new Size(21, 30)).ToString();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;produces this neat output:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;[ControlData:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;  Point    location    {X=12,Y=13} &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 51);"&gt;  Size    size    {Width=21, Height=30} ]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;Of course we could also have called &lt;code&gt; FieldsToString() &lt;/code&gt; directly as in:&lt;br /&gt;&lt;pre class="prettyprint"&gt;new ControlData(new Point(12, 13), new Size(21, 30)).FieldsToString();&lt;/pre&gt; with the same result.&lt;br /&gt;Important is that the &lt;span style="font-style: italic;"&gt;order of the yields&lt;/span&gt; in the GetFieldEnumerator() method exactly matches the &lt;span style="font-style: italic;"&gt;order in which the fields are declared&lt;/span&gt; int the class. Otherwise the values of the fields will not line up with their names.&lt;br /&gt;This requirement is caused by the fact, that the fieldnames are obtained from the class via reflection.&lt;br /&gt;&lt;br /&gt;Now, if we want to change any field names, we can go ahead and be sure that all necessary changes in order to produce the correct ToString() output  will be done automatically as we are not dealing with hard coded strings in the this method anymore.&lt;br /&gt;&lt;br /&gt;If we add another field &lt;span style="font-style: italic;"&gt;xxx &lt;/span&gt;, we just add a yield return &lt;span style="font-style: italic;"&gt;xxx&lt;/span&gt; to the GetFieldEnumrator() method and are done.&lt;br /&gt;&lt;br /&gt;Just to be clear, add the FieldsToString() method to your extension class and include the IFieldsEnumerable interface in the same project.&lt;br /&gt;&lt;br /&gt;Now you just need to implement this interface for the classes to which you want this extra functionality.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641640765672872979-4358735847271522483?l=thorstenlorenz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thorstenlorenz.blogspot.com/feeds/4358735847271522483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thorstenlorenz.blogspot.com/2009/06/more-extensions-generic-tostring-method.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default/4358735847271522483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default/4358735847271522483'/><link rel='alternate' type='text/html' href='http://thorstenlorenz.blogspot.com/2009/06/more-extensions-generic-tostring-method.html' title='More Extensions - The Generic ToString() Method for classes and structs'/><author><name>Thorsten Lorenz</name><uri>http://www.blogger.com/profile/11869165877618370852</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://2.bp.blogspot.com/_zO4YPCT1Z1Y/Sl8i1KY8CAI/AAAAAAAAAJQ/8gdBLNXtJtU/S220/keep.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1641640765672872979.post-6853244778203680148</id><published>2009-06-25T05:25:00.000-07:00</published><updated>2009-07-02T05:39:21.394-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='extension methods'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>Extension methods and Unit Testing</title><content type='html'>When unit testing, we soon find out, that the testing framework (like NUnit) will use the ToString() method of an object in order to show the reason why an Equality Assertion fails.&lt;br /&gt;Lets take or instance:&lt;br /&gt;&lt;blockquote style="color: rgb(102, 51, 255);"&gt;Assert.That(foo1,  Is.EqualTo(foo2));&lt;/blockquote&gt;If this test fails, NUnit will try to show you where the objects where different by using the ToString() method as such:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Expected string length 20 but was 21. Strings differ at index 3.&lt;br /&gt;Expected: "foo2 ToStringContent"&lt;br /&gt;But was:  "foo1 ToString Content"&lt;br /&gt;--------------^&lt;br /&gt;&lt;/blockquote&gt;The problem with that is, that if we list a lot of fields in our ToString() method, the above Action of NUnit will throw a null reference exception, if only one of these fields wasn't initilaized. This will happen more often when using Mock objects.&lt;br /&gt;In that case of course, we will never know what NUnit was trying to tell us. Not very desireable.&lt;br /&gt;&lt;br /&gt;Therfore I decided that I'd need a null safe ToString() method. Instead of throwing an exception if the object is null, it will just return a string, that tells me that it was null.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt; &lt;span style="color: rgb(102, 51, 255);"&gt;public static class NullSafe&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;{&lt;/span&gt; &lt;span style="color: rgb(102, 51, 255);"&gt; &lt;br /&gt;&lt;br /&gt;public static string ToStringNullSafe(this object obj)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;{&lt;/span&gt; &lt;span style="color: rgb(102, 51, 255);"&gt;     &lt;br /&gt;            return (obj != null) ? obj.ToString() : "NULL" ;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 255);"&gt; }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;If you put this into your extensions project we can change this:&lt;br /&gt;&lt;blockquote style="color: rgb(102, 51, 255);"&gt;public override string ToString()&lt;br /&gt; {&lt;br /&gt;&lt;br /&gt;string strM = (M != null) ? M.ToString() : "null";&lt;br /&gt;     string strName = (Name != null) ? Name.ToString() : "null";&lt;br /&gt;     string strStatisticTexts = (StatisticsTexts != null) ?        StatisticsTexts.Contents.ToString() : "null";&lt;br /&gt;&lt;br /&gt;     return string.Format("[ Type={0} M={1} Name={2} StatisticsTexts={3} ]",&lt;br /&gt;                                                                    M.GetType().Name, strM, strName, strStatisticTexts);&lt;br /&gt; }&lt;/blockquote&gt;to:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(102, 51, 255);"&gt;public override string ToString()&lt;br /&gt; {&lt;br /&gt;     return string.Format("[ Type={0} M={1} Name={2} StatisticsTexts={3} ]",&lt;br /&gt;                           M.GetType().Name,&lt;br /&gt;                           M.ToStringNullSafe(),&lt;br /&gt;                           Name.ToStringNullSafe(),&lt;br /&gt;                           StatisticTexts.ToStringNullSafe());&lt;br /&gt; }&lt;/blockquote&gt;While we are at it, there is still one problem: &lt;span style="font-style: italic;"&gt;M.GetType().Name&lt;/span&gt;&lt;br /&gt;This will also throw, if M is null.&lt;br /&gt;&lt;br /&gt;Again, extensions to the rescue. Add the following code to the NullSafe class:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;     &lt;span style="color: rgb(102, 51, 255);"&gt;  static class ObjectWasNull {}&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(102, 51, 255);"&gt;public static Type GetTypeNullSafe(this object obj)&lt;/span&gt; &lt;span style="color: rgb(102, 51, 255);"&gt;  &lt;br /&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: rgb(102, 51, 255);"&gt;return (obj != null) ? obj.GetType() : typeof(ObjectWasNull);&lt;/span&gt; &lt;span style="color: rgb(102, 51, 255);"&gt;  &lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;Note, that we just created the dummy class &lt;span style="font-style: italic;"&gt;ObjectWasNull&lt;/span&gt; in order to communicate, that the object in question was null.&lt;br /&gt;&lt;br /&gt;This will give us some helpfull output instead of failing totally.&lt;br /&gt;&lt;br /&gt;Lets show another example:&lt;br /&gt;Lets say we have a class:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(102, 51, 255);"&gt;class sut&lt;br /&gt; {&lt;br /&gt;     Panel uninitializedPanel;&lt;br /&gt;     public override string ToString()&lt;br /&gt;     {&lt;br /&gt;         return uninitializedPanel.ToString();&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;In the test we try the following:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;            &lt;span style="color: rgb(102, 51, 255);"&gt;sut sut1 = new sut();&lt;/span&gt; &lt;span style="color: rgb(102, 51, 255);"&gt;     &lt;br /&gt;sut sut2 = new sut();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;&lt;br /&gt;sut2.uninitializedPanel = new Panel();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 51, 255);"&gt;Assert.That(sut1, Is.EqualTo(sut2));&lt;/span&gt;&lt;/blockquote&gt;This will give us a very ugly message like:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic; color: rgb(192, 192, 192);"&gt;(......)&lt;br /&gt;System.NullReferenceException : Object reference not set to an instance of an object.&lt;br /&gt;at ( ...) TestClass.cs:line 145&lt;br /&gt;at System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args)&lt;br /&gt;at System.String.Format(IFormatProvider provider, String format, Object[] args)&lt;br /&gt;at System.IO.TextWriter.Write(String format, Object arg0)&lt;br /&gt;at NUnit.Framework.TextMessageWriter.WriteValue(Object val)&lt;br /&gt;at NUnit.Framework.TextMessageWriter.WriteExpectedValue(Object expected)&lt;br /&gt;at NUnit.Framework.TextMessageWriter.WriteExpectedLine(Object expected, Tolerance tolerance)&lt;br /&gt;at NUnit.Framework.TextMessageWriter.DisplayDifferences(Object expected, Object actual, Tolerance tolerance)&lt;br /&gt;at NUnit.Framework.Constraints.EqualConstraint.DisplayDifferences(MessageWriter writer, Object expected, Object actual, Int32 depth)&lt;br /&gt;at NUnit.Framework.Constraints.EqualConstraint.WriteMessageTo(MessageWriter writer)&lt;br /&gt;at NUnit.Framework.Assert.That(Object actual, IResolveConstraint expression, String message, Object[] args)&lt;br /&gt;at NUnit.Framework.Assert.That(Object actual, IResolveConstraint expression)&lt;br /&gt;(......)&lt;/blockquote&gt;Not very nice.&lt;br /&gt;Now lets change:&lt;br /&gt;&lt;blockquote style="color: rgb(102, 51, 255);"&gt;return uninitializedPanel.ToString();&lt;/blockquote&gt;to:&lt;br /&gt;&lt;blockquote style="color: rgb(102, 51, 255);"&gt;return uninitializedPanel.ToStringNullSafe();&lt;/blockquote&gt;&lt;br /&gt;and we get&lt;br /&gt;&lt;blockquote style="color: rgb(0, 204, 204); font-style: italic;"&gt;Test Failure : ( ... )&lt;br /&gt;Expected: System.Windows.Forms.Panel, BorderStyle:         &lt;br /&gt;System.Windows.Forms.BorderStyle.None&lt;br /&gt; But was:  NULL&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Much nicer indeed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1641640765672872979-6853244778203680148?l=thorstenlorenz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thorstenlorenz.blogspot.com/feeds/6853244778203680148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://thorstenlorenz.blogspot.com/2009/06/getting-it-on-with-extension-methods.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default/6853244778203680148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1641640765672872979/posts/default/6853244778203680148'/><link rel='alternate' type='text/html' href='http://thorstenlorenz.blogspot.com/2009/06/getting-it-on-with-extension-methods.html' title='Extension methods and Unit Testing'/><author><name>Thorsten Lorenz</name><uri>http://www.blogger.com/profile/11869165877618370852</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://2.bp.blogspot.com/_zO4YPCT1Z1Y/Sl8i1KY8CAI/AAAAAAAAAJQ/8gdBLNXtJtU/S220/keep.jpg'/></author><thr:total>0</thr:total></entry></feed>
