Archives

Archives / 2008 / February
  • LINQ to JSON beta

    Oh no, Beta! I like LINQ. A lot. For the past few months I have been fortunate to work on a .NET 3.5 project and I have been making heavily use of LINQ to XML. While using XLINQ it occurred to me that a similar API for working with JSON objects, which share a lot of similarities with XML, would be useful in many situations.

    This beta is a very rough early preview of LINQ to JSON. It was literally written in a weekend [:)] The aim is to get feedback and ideas on how the API could be improved.

    What is LINQ to JSON

    LINQ to JSON isn't a LINQ provider but rather an API for working with JSON objects. The API has been designed with LINQ in mind to enable the quick creation and querying of JSON objects.

    LINQ to JSON is an addition to Json.NET. It sits under the Newtonsoft.Json.Linq namespace.

    Creating JSON

    Creating JSON using LINQ to JSON can be done in a much more declarative manner than was previously possible.

    List<Post> posts = GetPosts();
     
    JObject rss = 
      new JObject(
        new JProperty("channel",
          new JObject(
            new JProperty("title", "James Newton-King"),
            new JProperty("link", "http://james.newtonking.com"),
            new JProperty("description", "James Newton-King's blog."),
            new JProperty("item",
              new JArray(
                from p in posts
                orderby p.Title
                select new JObject(
                  new JProperty("title", p.Title),
                  new JProperty("description", p.Description),
                  new JProperty("link", p.Link),
                  new JProperty("category",
                    new JArray(
                      from c in p.Categories
                      select new JValue(c)))))))));
     
    Console.WriteLine(rss.ToString());
     
    //{
    //  "channel": {
    //    "title": "James Newton-King",
    //    "link": "http://james.newtonking.com",
    //    "description": "James Newton-King's blog.",
    //    "item": [
    //      {
    //        "title": "Json.NET 1.3 + New license + Now on CodePlex",
    //        "description": "Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex",
    //        "link": "http://james.newtonking.com/projects/json-net.aspx",
    //        "category": [
    //          "Json.NET",
    //          "CodePlex"
    //        ]
    //      },
    //      {
    //        "title": "LINQ to JSON beta",
    //        "description": "Annoucing LINQ to JSON",
    //        "link": "http://james.newtonking.com/projects/json-net.aspx",
    //        "category": [
    //          "Json.NET",
    //          "LINQ"
    //        ]
    //      }
    //    ]
    //  }
    //}

    Querying JSON

    LINQ to JSON is designed with LINQ querying in mind. These examples use the RSS JSON object created previously.

    Getting the post titles:

    var postTitles =
      from p in rss.PropertyValue<JObject>("channel")
                  .PropertyValue<JArray>("item")
                  .Children<JObject>()
      select p.PropertyValue<string>("title");
     
    foreach (var item in postTitles)
    {
      Console.WriteLine(item);
    }
     
    //LINQ to JSON beta
    //Json.NET 1.3 + New license + Now on CodePlex

    Getting all the feed categories and a count of how often they are used:

    var categories =
      from c in rss.PropertyValue<JObject>("channel")
                  .PropertyValue<JArray>("item")
                  .Children<JObject>()
                  .PropertyValues<JArray>("category")
                  .Children<string>()
      group c by c into g
      orderby g.Count() descending
      select new { Category = g.Key, Count = g.Count() };
     
    foreach (var c in categories)
    {
      Console.WriteLine(c.Category + " - Count: " + c.Count);
    }
     
    //Json.NET - Count: 2
    //LINQ - Count: 1
    //CodePlex - Count: 1

    Feel free to make suggestions and leave comments. I am still experimenting with different ways of working with JSON objects and their values.

    Json.NET CodePlex Project

    LINQ to JSON - Json.NET 2.0 Beta - Json.NET source code and binaries

     

    kick it on DotNetKicks.com

  • DotNetKicks.com

    Marge, you can't kick me out of the house! You'll cause a miscount on the census! A miscount! For anyone who hasn't heard about this site yet, DotNetKicks.com is a community based news website. Basically it is a lot like Digg in that users submit and vote on articles, but unlike Digg it is focused exclusively on .NET news.

    Because the readers of DotNetKicks.com are all .NET developers, and they are the people that vote on what is important, you can be sure that the quality of articles that appears will always be high. Any important news or useful new tool will be sure to find its way onto the front page. You can keep up with .NET without being subscribed to a 100 different blogs

    If you have your own blog DotNetKicks.com can also be a great way to grow your readership. As a member you can submit your own blog posts for users to vote on. If the users find it interesting and "kick it" it will move onto the front page. A whole new community will be visiting your blog.

    DotNetKicks.com

    DotNetKicks.com Feed

     

    kick it on DotNetKicks.com *

    * The HTML for this button is generated by DotNetKicks.com when you submit a story.

  • Why I changed my mind about Extension Methods

    My initial impression of extension methods was that they would lead to confusing code.

    I imagined other developers picking up a project that used extension methods and being confused as to why ToCapitalCase() was being called on a string or wondering where AddRange(IEnumerable<T>) on that collection came from. Wouldn't it just be better to keep ToCapitalCase and AddRange as they currently are on helper classes?

    What changed my mind was actually using extension methods in anger myself. Using them firsthand I saw how extension methods could be used to improve both reading and writing C# code.

    More readable

    The nested nature of traditional static methods makes them counter-intuitive to read: You're essentially reading back to front. The static method call that comes first is actually what gets executed last.

    Say you wanted to get some nicely formatted XML from a file for logging purposes:

    string xml = XmlUtils.FormatXml(FileUtils.ReadAllText(PackageUtils.GetRelationshipFile(packageDirectory)));
    Logger.Log(xml);

    Now compare the same code using extension methods:

    string xml = packageDirectory.GetRelationshipFile().ReadAllText().FormatXml();

    The extension method version is much easier to comprehend compared to the first. It reads more like English.

    More intuitive to write

    Like extension methods are more intuitive to read, they are also more intuitive to write. You are no longer writing methods backwards in the order that they are called.

    Often when using static methods I find myself jumping back and forth. I am halfway through a statement when I realize that I want to use a static method with the current variable.

    Using the XML example above, being the non-omniscient scatter brain that I am, I probably wouldn't think to format the XML so it is nicely indented until I had the XML text. To format using a static method I would have to jump back to the beginning of the statement and add XmlUtils.FormatXml(...). With extension methods it would just be another method call onto the end of the statement.

    More discoverable

    "How are extension methods more discoverable than regular methods? What happens if they are in another namespace" you may be thinking. It is true that when compared with instance methods, extension methods come out worst off, but I believe that the comparison is flawed. Extension methods aren't for classes and frameworks which you are able to extend yourself, but for those which you can't.

    Jimbo: 'Hey Simpson, cool belt. Wanna trade?' Bart: 'Errr, no, cause yours is just a piece of extension cord...' Kearney: 'He's ragging on your cord, man...' Jimbo: 'Get him!' The better comparison is with traditional static methods. Once the required using statement is added, extension methods gain the upper hand with their superior intellisense support. Rather than a developer having to hunt through static helper objects trying to find whether the method he/she wants to use exists, the possible methods are displayed immediately in the member dropdown.

    Conclusion

    Extension methods are a lot like operator overloading. It is true that both have the potential to create a confusing mess when abused, they also both have real usability benefits when applied correctly, making code easier to write and easier to read.

    Use extension methods, but use them wisely [:)]

     

    kick it on DotNetKicks.com

    Here are some good examples of extension methods in the wild: