Hi and welcome to my blog. Im Tasos, a software engineer working in the UK. This is where i share some of my findings related with SQL, c#, asp.net and javascript with you. I hope you find something helpful and Im looking forward to your feedback!

Recent Comments

Popular Posts

Recent Posts

Archives

Post Categories

Blog Stats

  • Posts: 14
  • Comments: 36
  • Trackbacks: 16
  • Articles: 1

November 2007 Entries

C# 3.0 Anonymous type support is incomplete

posted @ Tuesday, November 27, 2007 2:54 AM | Feedback (3),

For those who have been playing with Linq and getting up to speed with the latest C# 3.0 features, you are most likely aware of the new language feature of Anonymous Types.

An anonymous type allows us to create and an instance of a an object whose type has not been defined in our code but whose properties are inferred from the object initializer.

The following example illustrates this by creating an instance of a variable of an unknown type that has 3 properties

var product = new
{
    Name = "Acme Rocket",
    Description = "The quick way to the moon",
Stock = 10 };

The variable type of product is not defined in our code. It is inferred through type inference and is of a compiler generated anonymous type that has 3 properties whose types again are inferred through type inference.


Anonymous types are a very powerful feature since they allow for creating LINQ projections without the need to define a class containing the projected fields of our query.

So in the following adapted sample taken from microsoft:

    string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
    var upperLowerWords =
        (from w in words
        select new { Upper = w.ToUpper(), Lower = w.ToLower() }).ToList();

    foreach (var ul in upperLowerWords)
    {
        Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower);
    }
 

upperLowerWords is an instance of an IEnumerable<anonymousType> and is also intellisensed as such:

image

This is all very good. We can create and use anonymous types in our code.

So what is the problem and why am I saying that anonymous type support is incomplete?

The problem lays in the fact that type inference only works on local variables. Which means that the anonymous type in our example (and anonymous types in general) is only useful as a strongly bound object in the scope of the procedure in which it has been created. Anonymous types cannot be returned as strongly typed objects in function return values. They can only be returned as objects as the following code shows


object
ReturnAnonymous() { return new { Name = "Acme Rocket", Description = "Quick way to the moon", Stock = 10}; }

There is an  interesting yet dirty workaround for returning  anonymous types and getting strongly typed access to a return value of type anonymousType from the calling code.

However, the suggested approach is to define a solid class in your code and use that as the return type instead of returning an anonymous type. In a LINQ Datalayer scenario this means that for each function that returns a projection of Data we would have to define and maintain empty classes that are merely there just to map to the projected object...

Further reading about this issue

Msdn forum post and proposed resolutions: 
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2434363&SiteID=1


Rick also talks about this issue in one of his posts (http://www.west-wind.com/WebLog/posts/33570.aspx)

I really enjoy the new features of C# 3.0 but not being able to return anonymous types across functions cripples the  potential of this language feature. This appears to be due to limitations in type inference which only works locally, and also seems to be a bit flaky if you ask me, from what I've been reading anyway:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=295134

http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx

 

Conclusion
Anonymous types even only accessible through local type inference are a really powerful language construct that have added value to LINQ queries (projections) . But I sure do look forward to seeing the C# compiler team unleashing the full potential of type inference and anonymous types by allowing us to return anonymous types as return values in our functions.

Yield return and Iterators use case: looping through the days between a date span

posted @ Thursday, November 15, 2007 11:54 PM | Feedback (6), Filed Under ASP.Net C#

I recently found myself in the situation where I had to loop through all the days from a StartDate to an EndDate.

Sure easy, all you need to do is something like this:

DateTime startDate = DateTime.Now;
DateTime endDate = DateTime.Now.AddDays(3);

DateTime curDate = startDate;
while (curDate <= endDate)
{
    //Do Something with curDate ...

    curDate = curDate.AddDays(1);
}

Does the job, but it is not very intuitive in my opinion. It is not that easy to read.
Wouldn't it be so much nicer if we could do something like this:

DayIterator dayIterator = new DayIterator(startDate, endDate);
foreach (DateTime dt in dayIterator)
{
     //Do Something with dt... 
}
 

I think the second version really shows the intent of what we are trying to do and is much more easy to follow and maintain.

So how do we go about implementing the DayIterator then? As you will see for yourself it really is simple code that makes use of the yield return statement for Iterators.

Here is the implementation of the DayIterator:

    public class DayIterator : IEnumerable<DateTime>
    {

        private DateTime _StartDate;
        private DateTime _EndDate;

        public DayIterator(DateTime startDate, DateTime endDate)
        {
            _StartDate = startDate;
            _EndDate = endDate;
        }

        public IEnumerator<DateTime> GetEnumerator()
        {
            DateTime currentDate = _StartDate;
            while (currentDate <= _EndDate) // Note that our Iterator is inclusive of endDate behaving like 'between'
            {
                yield return currentDate; // <-- This is the key line
                currentDate = currentDate.AddDays(1);
            }
        }

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            throw Exception("Not Implemented");
        }

        #endregion
    }
 

Thats all it takes! Now we have our custom DayIterator class. Now when we do foreach (DateTime dt in dayIterator) what foreach does is it calls GetEnumerator to start the loop. The yield return statement within GetEnumerator returns an instance of a DateTime class so the outer foreach loop starts looping using this as the first element. Each time our code reaches the foreach statement it calls GetEnumerator again resuming from the last yield return statement. When our GetEnumerator function finishes then the outer foreach loop stops looping. So in this example the GetEnumerator will finish when the condition
while (currentDate <= _EndDate) is not true anymore and therefore the foreach loop will terminate.

We can also use yield return break within the GetEnumerator implementation if we want to terminate the foreach looping.

So I guess some of you may be wondering What's with the two GetEnumerator functions instead of just one? Well In this example we want to loop through a collection of DateTime objects for this reason we inherited the DayIterator class from IEnumerable<DateTime>. This requires us to implement both the IEnumerable<DateTime> GetEnumerator() function and the IEnumerbale GetEnumerator (the latter returns only objects and we need not implement)

Ok, this is all good but does it really work?! Well, lets put it to the test with the following little sample code:


DateTime
startDate = DateTime.Now; DateTime endDate = DateTime.Now.AddDays(5); Console.WriteLine("StartDate: {0:dd MMM yyyy}", startDate); Console.WriteLine("EndDate: {0: dd MMM yyyy}", endDate); DayIterator dayIterator = new DayIterator(startDate, endDate); foreach (DateTime dt in dayIterator) { Console.WriteLine("In foreach: {0:dd MMM yyyy} ", dt); }


This is what we get:

image

 

Now the DayIterator Class can be easily expanded to include functions such as IsCurrentDayInSameMonthAsPrevious and the resulting code again looks even more elegant in a scenario where while we are looping through the days, we want to do something on when the month changes from one day to the next for example. It is quite straightforward to implement but as an excercise I will leave it up to you to implement :)

So if you find yourself looping in a for or a while loop, take another careful look at your code, you may be able to use an Iterator and express your code intent in a more clear and concise fashion. Of course this does not mean that we take it to the other extreme abandoning all loops for Iterators!

Question:
Can I implement the IEnumerbale GetEnumerator with the same logic as IEnumerable<DateTime> GetEnumerator() but without copying down the same code in two places, how?


Further Reading:
http://www.yoda.arachsys.com/csharp/csharp2/iterators.html
http://codebetter.com/blogs/david.hayden/archive/2006/10/05/C_2300_-2.0-Iterators-and-Yield-Keyword-_2D00_-Custom-Collection-Enumerators.aspx

Making your ASP:Repeater a little bit DRYer

posted @ Thursday, November 08, 2007 10:14 PM | Feedback (0), Filed Under ASP.Net

image

Dont Repeat Yourself, we see it all over, but yet the suggested way of doing things with a Repeater control makes many developers repeat code. Let me explain what I mean, say we want to use a repeater to render a table containing rows of alternating colors. Sure there is a GridView for this, but there are some cases when we would like to use the more lightweight repeater (especially if we just want a readonly representation and do not want editing capabilities)


As you already know, alternating rows in the repeater can be implemented by entering corresponding markup in the <ItemTemplate> tag for one style and more markup in the <AlternatatingItemTemplate> for the alternating template code. So we basically manage to end up with duplicate code just to set our style.

I mean, just look at the following snippet. The main markup is placed twice just to set the alternating row style.

<table>
    <asp:Repeater ID="Repeater1" runat="server">
        <ItemTemplate>
            <tr class="RowStyle0">
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "FirstName") %>
                </td>
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "LastName") %>
                </td>
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "Age") %>
                </td>
            </tr>
        </ItemTemplate>
        <AlternatingItemTemplate>
            <tr class="RowStyle1">
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "FirstName") %>
                </td>
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "LastName") %>
                </td>
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "Age") %>
                </td>
            </tr>
        </AlternatingItemTemplate>
    </asp:Repeater>
</table>

I just dont like seeing <AlternatingItemTemplate> in my code for something as simple as setting the style of a row.
The workaround is just to use the ItemTemplate and determine the css class of the each TR by evaluating the Container.ItemIndex modulo 2. So, here it goes:

<table>
    <asp:Repeater ID="Repeater2" runat="server">
        <ItemTemplate>
            <tr class="RowStyle<%# Container.ItemIndex % 2 %>">
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "FirstName") %>
                </td>
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "LastName") %>
                </td>
                <td>
                    <%# DataBinder.Eval(Container.DataItem, "Age") %>
                </td>
            </tr>
        </ItemTemplate>
    </asp:Repeater>
</table>

Just make sure you have a .RowStyle0{ } and .RowStyle1{ } in your css with your colors of choice

Now this is a simple showcase example, imagine having a more complex repeater (containing more columns). IMHO, avoiding the AlternatingItemTemplate leeds to DRYer, more maintainable code. Overall this is a very simple example but im pretty sure that we've all come across AlternatingItemTemplate for such a trivial task.