Archives

Archives / 2008 / May
  • Display nicely formatted .NET source code on your blog

    The best method of displaying nicely formatted code in a blog post in my experience is a Visual Studio plugin called CopySourceAsHtml.

    Once the plugin is installed simply select the code you want to display and choose Copy As HTML. A clean HTML representation of your code will be copied onto the clipboard which can then be pasted into your blog editor of choice (I like Windows Live Writer).

    You have to speak louder, I'm wearing a towel!

    The nice thing about CopySourceAsHtml is that the code on your blog looks exactly like it would in Visual Studio, right down to highlighting class names.

    CopySourceAsHtml also works on any file in Visual Studio be it C#, VB.NET, XML, HTML, XAML or JavaScript. The version of C# or VB.NET also doesn't matter.

    Finally CopySourceAsHtml works with almost any blog. Since it is just HTML there is nothing that needs to be done on the server.

    CopySourceAsHtml is free and can be download here. To get it up and running with VS2008 follow these instructions (its not hard).

    kick it on DotNetKicks.com

  • Slice - Collection Slicing Extension Method

    I really like Python collection slicing. It is easy to use, flexible and forgiving. Using C# 3.0 extension methods I have recreate collection slicing in .NET.

    List<int> initial = new List<int> { 1, 2, 3, 4, 5 };
     
    var sliced = initial.Slice(1, 4);
    // 2, 3, 4
     
    sliced = initial.Slice(0, 5, 2);
    // 1, 3, 5
     
    sliced = initial.Slice(null, null, -2);
    // 5, 3, 1
     
    sliced = initial.Slice(null, -1);
    // 1, 2, 3, 4
     
    sliced = initial.Slice(-2, -1);
    // 4

    Just specify the start index, stop index and a step and the method will create a new collection with all the valid values from the initial collection. Slice will never throw an IndexOutOfRange exception. If there are no values within the specified indexes then an empty collection is returned.

    Start, stop and step can all be negative. A negative start or stop will begin from the end of the collection (e.g. -1 becomes source.Count - 1) and a negative step will reverse the new collection.

    public static IEnumerable<T> Slice<T>(this IEnumerable<T> source, int? start)
    {
      return Slice<T>(source, start, null, null);
    }
     
    public static IEnumerable<T> Slice<T>(this IEnumerable<T> source, int? start, int? stop)
    {
      return Slice<T>(source, start, stop, null);
    }
     
    public static IEnumerable<T> Slice<T>(this IEnumerable<T> source, int? start, int? stop, int? step)
    {
      if (source == null) throw new ArgumentNullException("source");
     
      if (step == 0) throw new ArgumentException("Step cannot be zero.", "step");
     
      IList<T> sourceCollection = source as IList<T>;
      if (sourceCollection == null) source = new List<T>(source);
     
      // nothing to slice
      if (sourceCollection.Count == 0) yield break;
     
      // set defaults for null arguments
      int stepCount = step ?? 1;
      int startIndex = start ?? ((stepCount > 0) ? 0 : sourceCollection.Count - 1);
      int stopIndex = stop ?? ((stepCount > 0) ? sourceCollection.Count : -1);
     
      // start from the end of the list if start is negitive
      if (start < 0) startIndex = sourceCollection.Count + startIndex;
     
      // end from the start of the list if stop is negitive
      if (stop < 0) stopIndex = sourceCollection.Count + stopIndex;
     
      // ensure indexes keep within collection bounds
      startIndex = Math.Max(startIndex, (stepCount > 0) ? 0 : int.MinValue);
      startIndex = Math.Min(startIndex, (stepCount > 0) ? sourceCollection.Count : sourceCollection.Count - 1);
      stopIndex = Math.Max(stopIndex, -1);
      stopIndex = Math.Min(stopIndex, sourceCollection.Count);
     
      for (int i = startIndex; (stepCount > 0) ? i < stopIndex : i > stopIndex; i += stepCount)
      {
        yield return sourceCollection[i];
      }
     
      yield break;
    }

    kick it on DotNetKicks.com

  • Celebrating the Quick Hack

    How ironic. My crusade against television has come to an end so formulaic it could've spewed from the Powerbook of the laziest Hollywood hack. Sometimes you want something working now. Code that is understandable, maintainable, extensible and performant has its place but there are times you need a piece of functionality ASAP. Enter the quick hack.

    Below is a quick hack I did recently for a temporary dev tool. This isn't a post showing off a piece of code's elegancy or simplicity. Instead while it functioned perfectly and took no time to do, this code was so judged so unreadable and it performed so badly that I believe the hack deserves some kind recognition anyway.

    The Task

    Take a utility console application and turn it into a Windows Forms app that has a minimal UI.

    The Problem

    The console application writes a lot of debug data to the console. I want that information to be visible in the Winform app and so need to display the console output in a text area.

    The Quick Hack

    Sure you could abstract away writing to the console through a more generic logging interface and then replace every call to Console.Write, but that is far too smart and time consuming if you ask me [;)]

    Instead in the spirit of Quick Hack I chose to set my own TextWriter to Console.Out and have it write to the Winforms textbox.

    public class DelegateTextWriter : TextWriter
    {
      private readonly Encoding _encoding;
      private readonly Action<char> _writeAction;
     
      public DelegateTextWriter(Encoding encoding, Action<char> writeAction)
      {
        _encoding = encoding;
        _writeAction = writeAction;
      }
     
      public override Encoding Encoding
      {
        get { return _encoding; }
      }
     
      public override void Write(char value)
      {
        _writeAction(value);
      }
    }

    The TextWriter that will be set to Console.Out. Nothing too outrageous so far...

    Console.SetOut(new DelegateTextWriter(Console.OutputEncoding, c => {
        Invoke(new Action(() => ConsoleOutputTextBox.Text += c.ToString()));
    }));

    Haha! How deliciously unreadable.

    For the curious what is going on there is a lambda function is being created which takes a char. Because Console.Write is being called from a non UI thread we need to use Control.Invoke. The function creates another lambda function which adds the character to the end of the Winforms textbox. That lambda is called then passed to Invoke to be run.

    The icing on the cake is not only is it hard to understand at a glance but its also incredibly slow. For every single character being written to the console the app will:

    • Call two delegates
    • Call Control.Invoke
    • Turn the character being written into a string
    • Create a new string of the entire contents of the textbox so far plus the new character

    No wonder it maxed out a CPU core and output got written to the textbox like a type writer.

    After showing off how awesomely bad this hack was I did spend a couple of minutes making it usable. Splitting the code up and adding comments made it somewhat understandable and to fix performance all that was needed was an override for TextWriter.Write(char[]) and replacing the string concatenation with TextBox.AppendText.

     

    If you have any quick hacks of your own that you are proud of (both elegant and horrible) I would love to hear them.

  • Json.NET 2.0 Released

    Public transportation is for jerks and lesbians. The final version of Json.NET 2.0 is now available for download. The notable new feature(?) of this release is Json.NET now includes documentation. I know, I am just as shocked as you are!

    Json.NET - Quick Starts & API Documentation

    Overall I am really proud of how Json.NET 2.0 has turned out. From a usability perspective the new LINQ to JSON API makes manually constructing and reading JSON considerably easier compared to the old JsonReader/JsonWriter approach. The JsonSerializer has also seen big user improvements. New settings and attributes allow a developer to have far greater control over the serialization/deserialization process.

    Architecturally I am also pleased with Json.NET 2.0. LINQ to JSON builds on top of the existing Json.NET APIs and there was a lot of reuse between the different Json.NET components: JsonReader/Writer, JsonSerializer and the LINQ to JSON objects. Features that I thought might a lot of time and code to implement turned out to be quite simple when I realised I could reuse a class from somewhere else.

    Changes

    Here is a complete list of what has changed since Json.NET 1.3:

    Json.NET 2.0 Final

    • New feature - Documentation.chm included in download. Contains complete API documentation and quick start guides to Json.NET.

    Json.NET 2.0 Beta 3

    • New feature - Added JsonObjectAttribute with ability to opt-in or opt-out members by default.
    • New feature - Added Skip() method to JsonReader.
    • New feature - Added ObjectCreationHandling property to JsonSerializer.
    • Change - LOTS of little fixes and changes to the LINQ to JSON objects.
    • Change - CultureInfo is specified across Json.NET when converting objects to and from text.
    • Change - Improved behaviour of JsonReader.Depth property.
    • Change - GetSerializableMembers on JsonSerializer is now virtual.
    • Fix - Floating point numbers now use ToString("r") to avoid an overflow error when serializing and deserializing a boundary value.
    • Fix - JsonSerializer now correctly serializes and deserializes DBNull.
    • Fix - JsonSerializer no longer errors when skipping a multi-token JSON structure.
    • Fix - Clone a JToken if it already has a parent and is being added as a child to a new token

    Json.NET 2.0 Beta 2

    • New feature - Added FromObject to JObject, JArray for creating LINQ to JSON objects from regular .NET objects.
    • New feature - Added support for deserializing to an anonymous type with the DeserializeAnonymousType method.
    • New feature - Support for reading, writing and serializing the new DateTimeOffset type.
    • New feature - Added IsoDateTimeConverter class. Converts DateTimes and DateTimeOffsets to and from the ISO 8601 format.
    • New feature - Added JavaScriptDateTimeConverter class. Converts DateTimes and DateTimeOffsets to and from a JavaScript date constructor.
    • New feature - XmlNodeConverter handles serializing and deserializing JavaScript constructors.
    • New feature - Ability to force XmlNodeConverter to write a value in an array. Logic is controlled by an attribute in the XML, json:Array="true".
    • New feature - JsonSerializer supports serializing to and from LINQ to JSON objects.
    • New feature - Added Depth property to JsonReader.
    • New feature - Added JsonTextReader/JsonNodeReader and JsonTextWriter/JsonNodeWriter.
    • Change - More concise LINQ to JSON querying API.
    • Change - JsonReader and JsonWriter are now abstract.
    • Change - Dates are now serialized in a JSON complient manner, similar to ASP.NET's JavaScriptSerializer or WCF's DataContractJsonSerializer.
    • Change - JsonSerializer will serialize null rather than throwing an exception.
    • Change - The WriteTo method on LINQ to JSON objects now support JsonConverters.
    • Fix - JsonTextReader correctly parses NaN, PositiveInfinity and NegativeInfinity constants.
    • Fix - JsonSerializer properly serializes IEnumerable objects.
    • Removed - AspNetAjaxDateTimeConverter. Format is no longer used by ASP.NET AJAX.
    • Removed - JavaScriptObject, JavaScriptArray, JavaScriptConstructor. Replaced by LINQ to JSON objects.

    Json.NET 2.0 Beta 1

    • New feature - LINQ to JSON!
    • New feature - Ability to specify how JsonSerializer handles null values when serializing/deserializing.
    • New feature - Ability to specify how JsonSerializer handles missing values when deserializing.
    • Change - Improved support for reading and writing JavaScript constructors.
    • Change - A new JsonWriter can now write additional tokens without erroring.
    • Bug fix - JsonSerializer handles deserializing dictionaries where the key isn't a string.
    • Bug fix - JsonReader now correctly parses hex character codes.

    Json.NET CodePlex Project

    Json.NET 2.0 Download - Json.NET source code, binaries and documentation

    kick it on DotNetKicks.com