Kurser och utbildning av IT-proffs och systemutvecklare

i Sök

Cornerstones utvecklarblogg

Alla Taggar

All Tags » .Net Framework 3.5   (RSS)
Sorry, but there are no more tags available to filter with.

  • The MVC Framework from Microsoft

    I have just got back from a whole week tour with Microsoft. T talked about some Tips & Tricks regarding ASP.Net AJAX. In the next week I will be on a new tour where I’m going to talk about “how to write beautiful code” (Pimp my code).

    Many of you have probably already heard about the MVC Framework the ASP.Net team are working on, if not read about it here. During the Developer Summit next year, I'm probably going to talk about the framework.

    A preview of the framework will be available at the same time as VS 2008 RTM, around the end of February 2008. Then it will be built-in to .Net 3.5 SP1. I’m not sure if SP1 of .Net 3.5 is the “package” that will also have the first version of the ADO.Net Framework. The only thing I know is that it will be shipped in an update after the RTM of VS 2008 is released and somewhere around when SQL Server2008 is released.

    About the MVC patterns, I have earlier written about the “MVP” pattern, if you haven’t read about it, here is the post:

    http://fredrik.nsquared2.com/ViewPost.aspx?PostID=416



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • The launch of Visual Studio 2008, SQL Server 2008 and Windows Server 2008

    Several people have asked me when the next versions of Microsoft products will be launched. Next year Microsoft will have a launch event for the products in Las Vegas, the date is set to Feb. 27 th 2008. You can read more about it here.



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • Extension methods in C# 3.0

    This post is going to be about extension method that is added to C# 3.0 that will be released with Visual Studio “Orcas” (next version of Visual Studio). (Yes I know that several people have already wrote about extension methods etc, but I assume some of my readers haven't seen it yet.) In this post I’m going to have 3 classes, Order, OrderRow and Product. Here is a simple implementation of the three:

    Order.cs

    public sealed class Order
    {
            private List<OrderRow> _orderRows;

            public List<OrderRow> Rows
            {
                get { return this._orderRows; }
                set { this._orderRows = value; }
            }
    }

    OrderRow.cs

    public class OrderRow
    {
            private Product _product;
            private int _quantity = 0;

            public Product Product
            {
                get { return this._product; }
                set { this._product = value; }
            }

            public int Quantity
            {
                get { return this._quantity; }
                set { this._quantity = value; }
            }
    }

    Product.cs

    public class Product
    {
            private string _name;
            private string _category;
            private double _price = 0.0;

            public string Name
            {
                get { return this._name; }
                set { this._name = value; }
            }


            public string Category
            {
                get { return this._category; }
                set { this._category = value; }
            }


            public double Price
            {
                get { return this._price; }
                set { this._price = value; }
            }
    }

    Note: The classes are poor, they should normally have more properties etc, but I don’t need to use more for this post.

    Something that is important to observe in the code above is that the Order class is sealed. So we can’t inherit the class and extend it with more members. Normally I usually implement my classes by default as immutable and adding the set methods when I need to. But in this post I will not, it’s because I’m going to use Object Initialization.

    If I want to add code that will count the price of the order I can write something like:

    double totalPrice = 0.0;

    foreach (OrderRow row in order.Rows)
    {
        totalPrice += row.Product.Price * row.Quantity;
    }

    Because I can’t add this code into a sealed class I can instead use a static method to make sure I can re-use the code:

    public static class OrderExtension
    {
         public static double TotalPrice(Order order)
         {
             double totalPrice = 0.0;

             foreach (OrderRow row in order.Rows)
             {
                  totalPrice += row.Product.Price * row.Quantity;
             }

             return totalPrice;
         }
    }

    Now I can re-use the method to get the total price of an order anywhere in my application. I just write:

    double totalPrice = OderExtenstion.TotalPrice(myOrder);

    Note: Some developers should probably add the TotalPrice to the Order class from the beginning, but I did not because of demonstration purpose of extension methods.

    Let’s assume that I suddenly need to calculate the total price of an order, but only on order rows that have a product form a specific category, for example “Book”. To do this I add a new method to our OrderExtension class:

    public static double TotalPriceOfACategory(Order order, string category)
    {
           double totalPrice = 0.0;

           foreach (OrderRow row in order.Rows)
           {
                if (row.Product.Category == category)
                     totalPrice += row.Product.Price * row.Quantity;
           }

           return totalPrice;
    }

    To get the total price of all the books in the order we simply write:

    double totalPrice = OrderExtension.TotalPriceOfACategory(order, "Book");

    Now instead of calling the static method of the OrderExtension I really want to have the methods added to the Order class. Even if the Order is sealed I can actually extend it by using extension methods. To extend an already existing type I create a static class with static method, which I already have done.  Then I add “this <type> name” as the first argument to the static methods. “this” is used to specify which type I want extend, in my case the Order type. Because the static method I already have created takes a Order as the first argument, I simply add “this” before the type and the Order type is now extended with the methods:

    public static class OrderExtension
    {
        public static double TotalPrice(this Order order)
        {
            double totalPrice = 0.0;

            foreach (OrderRow row in order.Rows)
            {
                totalPrice += row.Product.Price * row.Quantity;
            }

            return totalPrice;
        }

        public static double TotalPriceOfACategory(this Order order, string category)
        {
            double totalPrice = 0.0;

            foreach (OrderRow row in order.Rows)
            {
                if (row.Product.Category == category)
                     totalPrice += row.Product.Price * row.Quantity;
            }

            return totalPrice;
        }
    }

    Now I can remove the call to the static method and instead write:

    double totalPrice = order.TotalPrice ();

    double totalPrice = order.TotalPriceOfACategory("Book");

    As you can see the first argument of the method with “this” before the type is removed. Instead the argument will work as the current instance of the class the method extends. Extension method is kind of a poor man’s mixin solution.

    Now let us move on by simplify the code a little bit. If we look at the code we can see that I do something twice, the foreach and the line that calculate the price. Doesn’t the code smell!? I think so, so let’s refactoring. Instead of using two methods that have almost the same kind of code, I will create two other methods and use a delegate. So I remove the TotalPriceOfACategory method and also add a new TotalPrice method and change the old TotalPrice to take a delegate as an argument, so the new extension will look like this:

    public static class OrderExtension
    {
           public static double TotalPrice(this Order order)
           {
                return order.TotalPrice(null);
           }

           public static double TotalPrice(this Order order, Predicate<OrderRow> predicate)
           {
                double totalPrice = 0.0;

                foreach (OrderRow row in order.Rows)
                {
                    if (predicate == null || predicate(row))
                        totalPrice += row.Product.Price * row.Quantity;
                }

                return totalPrice;
           }
    }

    So what this new code does is to check if the passed Predicate delegate should be executed or not. If I use the first TotalPrice where I don’t pass a Predicate delegate, it will pass null as an argument and calculate the total price of the whole order. If I pass a Predicate it will call it and only calculate the price if the predicate return true. The following code can now be used to calculate the total price based on a specific category (I will use an anonymous delegate to make the code simple):

    totalPrice = order.TotalPrice(delegate(OrderRow row) { return (row.Product.Category == "Book"); });


    totalPrice = order.TotalPrice();

    As you can see I pass an anonymous delegate which will check if the category is “Book”. Instead of using anonymous delegate we can use lambda in C# 3.0. So the code can now look like:

    totalPrice = order.TotalPrice(row => row.Product.Category == "Book");

    Maybe you wonder why I pass a delegate and do not only pass an argument with the category to the code, and do the check against it instead of calling the delegate. Well if we need to change the logic by some reason, maybe only calculate the total price where the quantity is more than 1 (if not give it away free), we could now simply write:

    totalPrice = order.TotalPrice(row => row.Quantity > 1);

    Well, this code is not the ultimate code for a TotalPrice calculation solution; it’s just used in this post as a demonstration about extension methods etc, so don’t hang up on the implementation of the method, just see the benefits with extension methods and lambda etc.

    Let’s assume I need a method that can find all OrderRows based on a criterion, for example I need to find all order rows within an order that has a specific category. In this case I will extend the Order type with a FindRows method. So I add a new extension method to the OrderExtension class that will look like this:

    public static List<OrderRow> FindRows(this Order order, Predicate<OrderRow> predicte)
    {
        return order.Rows.FindAll(predicte);
    }

    In this code I take the advantage of the List<> object’s FindAll method that takes a predicate. I could of course instead of adding the FindRows method just use the Order.Rows.FindAll method, but assume the FindAll doesn’t exists and the FindRows will sort of implement a similar method. When the FindRows method is added I can now use lambda to get a list of OrderRows that have a product with the category book and for example display the name of the books:

    foreach (OrderRow orderRow in order.FindRows(row => row.Product.Category == "Book"))
              Console.WriteLine(orderRow.Product.Name);

    With LINQ I can actually ignore adding the FindRows method and instead use a query in C# to find all rows with a product with a specific category. It could instead look like this:

    var rows = from n in order.Rows
               where n.Product.Category == "Book"
               orderby n.Product.Name
               select n;

    foreach (OrderRow orderRow in rows)
        Console.WriteLine(orderRow.Product.Name);

    Well the LINQ part in this post was more like a bonus ;)



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se

Den här bloggen

Syndication