Rainer's profileCyrons BlogPhotosBlogListsMore Tools Help

Blog


    August 16

    AntiFor patterns

    I have read Matthew Podwysocki’s AntiFor campaign article recently and I wondered wether it is possible to substitute all kinds of for-loops with LINQ expressions.
    This came back to my mind when I wrote a little application yesterday which consists of some for-loops.
    Here are the three methods with for-loops and their counterparts which use LINQ, so you can compare them directly.

    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace AntiForVersuche
    {
       public class AntiFor
       {
          //======================================================================
     
          // Spaltet einen multiline-Text in einzelne Zeilen und setzt diese in ein String-Array.
          public string[] SplitText2LinesWithFor(string text)
          {
             char[] splitCharacters = { '\n' };
             var lines = text.Split(splitCharacters);
             for(var i = 0; i < lines.Length; i++)
             {
                lines[i] = lines[i].TrimEnd('\r');
             }
             return lines;
          }
     
          public IEnumerable<string> SplitText2LinesWithLinq(string text)
          {
             char[] splitCharacters = { '\n' };
             if(text == null)
                return null;
             string[] lines = text.Split(splitCharacters);
             var query = lines.Select(value => value.TrimEnd('\r'));
             return query;
          }
     
          //======================================================================
     
          // Setzt drei Slashes vor jede Zeile.
          public string[] PrependXmlCommentSignsWithFor(string[] lines)
          {
             var result = new string[lines.Length];
             for(int i = 0; i < lines.Length; i++)
             {
                result[i] = "///" + lines[i];
             }
             return result;
          }
          
          public IEnumerable<string> PrependXmlCommentSignsWithLinq(IEnumerable<string> lines)
          {
             if(lines == null)
                return null;
             if(lines.Count() == 0)
                return null;
             var query = lines.Select(value => "///" + value);
             return query;
          }
     
          //======================================================================

     

    // Fügt die einzelnen Zeilen wieder zu einem Multiline-Text zusammen.

          public string ConcatenateLinesWithFor(string[] lines)
          {
             var builder = new StringBuilder();
             for(int i = 0; i < lines.Length; i++)
             {
                builder.AppendLine(lines[i]);
             }
             return builder.ToString();
          }
     
          public string ConcatenateLinesWithLinq(IEnumerable<string> lines)
          {
             if(lines == null)
                return null;
             if(lines.Count() == 0)
                return null;
             string query = lines.Aggregate((build, line) => build + "\r\n" + line);
             query += "\r\n";
             return query;
          }
       }
    }

    Conclusion


    Well, these three samples sure don’t answer my initial question to my utter satisfaction but they showed me some of the possibilities and I’m confident. It has been a pretty informative piece of work for me because I never used the Select and Aggregate Extension methods before. Maybe this blog post is as informative for some of you out there as it has been for me.
    August 11

    Software-Eigenmächtigkeiten

    Nicht nur daß die Installation von Windows Live Essentials meine IE-Startseite geändert hat, ohne mich zu fragen GRRRRRRR!!!!!!! >:-(

    nein, dieses Miststück von Messenger startet sich jedesmal bei dem Besuch einer Webseite, die irgendwas mit Windows live zu tun hat (wie z.B. mein Blog) von selber – obwohl ich in den Optionen eingestellt habe daß er das nicht soll!!!
    Ich schmeiß diesen Dreck in die Tonne!!!!!!!!

    Hat jemand ‘ne Gif-Animation die das Messenger-Icon erschießt?

    August 10

    NUnit, a competitor for MS-Test, which you shouldn’t let pass by without a closer look!

    I hesitated a long time. I use MS-Test, PEX and CHESS. Shouldn’t that be enough? Why the heck another unit test framework? Reading “The Curse of the Rewrite” from Tim Ross got me curious today (and most of all after I saw the code, wich uses NUnit). That blog post deals with testing of legacy code – but that’s just a side note.
    So what’s special about NUnit? Well, just look at this line of code:

    Assert.That(documentManager, Is.InstanceOfType(typeof(DocumentManager)), "Should create an instance of DocumentManager");


    It’s code which fulfills the BDD paradigm at last! So I downloaded and installed NUnit, looked at the syntax sample and I’m convinced ever since.
    If you have never heard of NUnit or still hesitate as I did before, than just take a look at this syntax sample. It’s right from the installation. I hope they don’t sue me for this. It’s pure advertising (but an honest one ;-) ).

    // ****************************************************************
    // Copyright 2007, Charlie Poole
    // This is free software licensed under the NUnit license. You may
    // obtain a copy of the license at http://nunit.org/?p=license&r=2.4
    // ****************************************************************
     
     
    // Cropped due to text length constraints in this blog. :-/
    // ...
    // The original code is much longer!
     
          [Test]
          public void IsTrue()
          {
             // Classic syntax
             Assert.IsTrue(2+2==4);
     
             // Helper syntax
             Assert.That(2+2==4, Is.True);
             Assert.That(2+2==4);
     
             // Inherited syntax
             Expect(2+2==4, True);
             Expect(2+2==4);
          }
     
          [Test]
          public void IsFalse()
          {
             // Classic syntax
             Assert.IsFalse(2+2==5);
     
             // Helper syntax
             Assert.That(2+2== 5, Is.False);
             
             // Inherited syntax
             Expect(2+2==5, False);
          }
     
    // Cropped due to text length constraints in this blog. :-/
    // ...
    // The original code is much longer!
          
          [Test]
          public void CollectionContainsTests()
          {
             int[] iarray = new int[] { 1, 2, 3 };
             string[] sarray = new string[] { "a", "b", "c" };
     
             // Classic syntax
             Assert.Contains(3, iarray);
             Assert.Contains("b", sarray);
             //...
     
             // Helper syntax
             Assert.That(iarray, Has.Member(3));
             Assert.That(sarray, Has.Member("b"));
             Assert.That(sarray, Has.No.Member("x"));
             //...
          
             // Inherited syntax
             Expect(iarray, Contains(3));
             Expect(sarray, Contains("b"));
             Expect(sarray, Not.Contains("x"));
     
             //...
          }
     
          // ...
     
          [Test]
          public void SubsetTests()
          {
             int[] ints1to5 = new int[] { 1, 2, 3, 4, 5 };
     
             // Classic syntax
             CollectionAssert.IsSubsetOf(new int[] { 1, 3, 5 }, ints1to5);
             CollectionAssert.IsSubsetOf(new int[] { 1, 2, 3, 4, 5 }, ints1to5);
             CollectionAssert.IsNotSubsetOf(new int[] { 2, 4, 6 }, ints1to5);
             CollectionAssert.IsNotSubsetOf(new int[] { 1, 2, 2, 2, 5 }, ints1to5);
     
             // Helper syntax
             Assert.That(new int[] { 1, 3, 5 }, Is.SubsetOf(ints1to5));
             Assert.That(new int[] { 1, 2, 3, 4, 5 }, Is.SubsetOf(ints1to5));
             Assert.That(new int[] { 2, 4, 6 }, Is.Not.SubsetOf(ints1to5));
          
             // Inherited syntax
             Expect(new int[] { 1, 3, 5 }, SubsetOf(ints1to5));
             Expect(new int[] { 1, 2, 3, 4, 5 }, SubsetOf(ints1to5));
             Expect(new int[] { 2, 4, 6 }, Not.SubsetOf(ints1to5));
          }
          #endregion
     
          #region Property Tests
          [Test]
          public void PropertyTests()
          {
             string[] array = { "abc", "bca", "xyz", "qrs" };
             string[] array2 = { "a", "ab", "abc" };
             ArrayList list = new ArrayList( array );
     
             // Not available using the classic syntax
     
             // Helper syntax
             Assert.That( list, Has.Property( "Count" ) );
             Assert.That( list, Has.No.Property( "Length" ) );
     
             // ...

    Do you know any other unit test framework which can beat this? Let me know!

    August 03

    Sample code in help files, namespace descriptions and angle brackets in XML comments. How to get around these hurdles.

    This tutorial will show you how to add sample code into your custom help files. It will not show you how to make help files in general because you can find several tutorials for this in the internet. Just one tip:
    Get Sandcastle from Microsoft at
    http://www.microsoft.com/downloads/details.aspx?familyid=E82EA71D-DA89-42EE-A715-696E3A4873B2&displaylang=en

    and the Sandcastle help file builder from codeplex.
    http://www.codeplex.com/SHFB

    You can also find a “Getting started” section in the Sandcastle help file builder documentation. 

    Now let's go:
    At first you must enable XML documentation file in the build section of the project properties.

    image

    Writing the sample code
    To add sample code, you have to write (and test!) it first, of course.

    using System;
     
    namespace XmlCommentSampleCodeDemo
    {
       class DemoCode
       {
          // This is the demo code which will be inserted into the XML-comment of the AddWorldTo-method.
          public void Demo()
          {
             MyClass instance = new MyClass();
             string myString = "Hello";
             string result = instance.AddWorldTo(myString);
             Console.WriteLine(result);
          }
       }
    }

    A demo class with inserted sample code
    Just copy and paste the demo code into the XML-comment block as shown below. Notice that the code is surrounded by a <code>-Section which is contained in an <example>-section.

    namespace XmlCommentSampleCodeDemo
    {
       /// <summary>
       /// This class is just a sample for the XML documentaion.
       /// You will see this line at the class level in the help file.
       /// </summary>
       public class MyClass
       {
          /// <summary>
          /// Adds " world." to a string.
          /// </summary>
          /// <param name="someString">Any string.</param>
          /// <returns>A modificated string.</returns>
          /// <example>
          /// <code>
          /// public void Demo()
          /// {
          ///    MyClass instance = new MyClass();
          ///    string myString = "Hello";
          ///    string result = instance.AddWorldTo(myString);
          ///    Console.WriteLine(result);
          /// }
          /// </code>
          /// </example>
          public string AddWorldTo(string someString)
          {
             return someString + " world.";
          }
       }
    }

     

    The help entry
    After generating the helpfile with Sandcastle help file builder, the entry for the AddWorldTo method will look like this:

    image

    Namespace comments
    Namespace comments are special because you cannot comment a namespace by default. Hopefully this will change with a future release of Visual Studio. Meanwhile you need the following trick to achieve this goal.

    namespace XmlCommentSampleCodeDemo
    {
       // Add this empty class in conjunction with this attribute to your project.
     
       /// <summary>
       /// This is just an entry to demonstrate a namespace comment.
       /// </summary>
       [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
       class NamespaceDoc
       {
       }
    }

    Here you can see the comment for the namespace in the help.

    image 

    How to get angle brackets in a code example
    When you have angle brackets the compiler will warn you about inappropriate tags. This is simply because either the XML file with the comments as the code inside the comments use them together. To overcome this problem you have to surround the code with a <![CDATA[ ]]> tag.
    Here is an example:

    /// <summary>
          /// My method.
          /// </summary>
          /// <param name="stringList">The string list.</param>
          /// <example>
          /// <code>
          /// <![CDATA[
          /// // This is no usage example.
          /// public void MyMethod(List<string> stringList)
          /// {
          ///   //...
          /// }
          /// ]]>
          /// </code>
          /// </example>
          public void MyMethod(List<string> stringList)
          {
             //...
          }


    This is what it looks like in the help.
    image

    Note: You could also use HTML-tags for the angle brackets but

    1. it looks distracting and
    2. it’s likeley to forget or overlook them here and there. With the compilation time of the help file in mind, it’s very annoying when that happens.