Saturday, May 31, 2008

Now! That has to be one of my greatest findings! Ever!

The Indexer method (the one that allows for doing object[something]) of the Hashtable class in .NET has a Thread.Sleep(1) inside one of the loops!!!!

Yes I repeat Thread.Sleep(1)!

Why would anyone want to insert a Thread.Sleep() call in to a Hashtable, or any other BCL class for that matter, is beyond me.

Can you beat this gem?

Saturday, May 31, 2008 9:09:21 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [7]  | 
 Wednesday, May 21, 2008

"There is no such method!" That's what everyone is told by Microsoft. Microsoft is even insolent enough to provide us with reasons why they did not include Directory.Copy method in .NET Framework.

I find those arguments unacceptable. Sure, they are valid at some level, but it's wouldn't be the only piece of code that goes "mainstream" and does what 99% of people would expect it to do, without considering special cases.

So I went and almost implemented my own Directory.Copy. Almost.

It came out that Microsoft does not live to its own words! There is a method in .NET Framework, that allow us to copy a directory, just like that, in one call. It is hidden in a Microsoft.VisualBasic.dll assembly in a Microsoft.VisualBasic.FileIO.FileSystem type and is called (not surprisingly) CopyDirectory.

Although it is in VisualBasic namespace, there is nothing that prevents us from using it in C#. Only a reference to an assembly is needed.

Well Microsoft? What you say to that?

Wednesday, May 21, 2008 8:07:50 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 

Another day, another gotcha.

While working with regular expressions I was matching some input string to a pattern with one group capture (is it the correct name?). I made a regex.Match() thing, got a match and since it was just a test code, I wen stright for getting the second group out of the match (first being the whole match):

DoSomething(match.Groups[1].Value);

I was pretty much expecting an IndexOutOfRangeException, or something similar, in case there were no matches. To my surprise I got no exception! To the contrary I got a result, an empty one, but a result.

Quick peek inside the code and it came out, that that's just how GroupCollection's indexer is implemented. It returns an empty group in case you try to get one that doesn't exist.

Is it intuitive? I seriously doubt it. That's a first time I see a collection with an indexer, that allows me to access elements by index that is beyond the collection's elements count!

I don't like when those kinds of things happen...

Wednesday, May 21, 2008 7:54:36 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 

Just few days ago, my friend at work found a peculiar error message in ASP.NET RangeValidator control. He was trying to validate length of a string in a TextBox. Controls on page definded as follows:

<asp:TextBox runat="server" ID="TB" />
<asp:RangeValidator runat="server" ID="RV" 
MinimumValue="3" MaximumValue="20" 
ControlToValidate="TB" Type="String" />

What he got was a best error message ever:

"The MaximumValue 20 cannot be less than the MinimumValue 3"

That's right! 20 cannot be less than 3!

Interesting isn't it?

I made some research of my own and I've found out that sane people should not look inside RaneValidator's (and other related classes) code! What it does inside is it uses a String.Compare to check if ranges are ok.

Of course, the problem are not the ranges, but the Type property of a validator. If set to String, it treates minimum and maximum values as strings and compares them as such - meaning that it compares character by character instead of just number to number.

That explains, why my friend got the error, but it certainly does not justify the text of the message! It might take long hours for an inexperienced developer to find where the problem lies. Come on Microsoft! You can do better than that!

Funny thing is that I never even thought about using RangeValidator to ensure string length, but suggested RegularExpressionValidator right from the start :-).

Wednesday, May 21, 2008 7:44:48 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [5]  | 
 Saturday, May 17, 2008

As we all know, ASP.NET uses one form model to do all it's magic. Love it or hate it, we have to live with it. 99% of the time, it is not a problem, but then there is this 1%...

The main problem with ASP.NET's model is that the form tag has a fixed action attribute. What if we want to change it? No, there is no simple way of doing it. Solutions vary. Most common one is to create your own FormControl that inherits from HtmlForm and override RenderAttributes method. Unfortunately, inside that method, we have to do everything the original method does and only change the action attribute to the desired value. Ugly!

Another one is to provide an OutputFilter for the Response but that is also a lot of coding.

My preferred way of dealing with this issue is to provide my own, special HtmlTextWriter. Its role is to intercept the WriteAttribute method call and provide my own value. Following code illustrates the concept:

class ActionAttributeWriter
    : HtmlTextWriter
{
    string action;
    public ActionAttributeWriter(
        HtmlTextWriter writer, string action)
        : base(writer)
    {
        this.action = action;
    }
    public override void WriteAttribute
        (string name, string value, bool fEncode)
    {
        if (name == "action")
        {
            value = action; 
        }
        base.WriteAttribute(name, value, fEncode);
    }
}

Only thing that is needed then is to use this writer instead of a normal one. Page.CreateHtmlTextWriter can be used for this purpose:

protected override HtmlTextWriter 
    CreateHtmlTextWriter(System.IO.TextWriter tw)
{
    ActionAttributeWriter writer = 
        new ActionAttributeWriter(
            base.CreateHtmlTextWriter(tw), 
            "action");
    return writer;
}

Solution is not very clean and I would certainly not recommend it for a public product, but it's better than nothing.

Saturday, May 17, 2008 2:09:17 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  | 
 Saturday, April 05, 2008

Today I needed to add an special field to my LINQ query. A kind of Row Number column. Actually it was not a row number nor was it a column since LINQ deals with objects, but since it was used for presenting data in a tabular way, I see no other name that fits the description.

So, I needed a data displayed in a following format:

Lp. Name
1 Murray N. Rothbard
2 Hans-Hermann Hoppe
3 Ludwig von Mises

First column had to be generated somehow. Using LINQ. I made few quick searches on google, but whith no success, so I came out with my own solution:

int i = 1;
return from author in DataContext.Authors
       select new Author() { Lp = i++, Name = author.Name };

So very simple. Isn't it?

Friday, April 04, 2008 11:15:34 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [9]  | 
 Wednesday, April 02, 2008

Today while using Reflector I've noticed one funny thing. It came out, that we are able to see where Microsoft keeps their PublicKey files and what are their names :-)

Few samples:

mscorlib f:\RedBits\Tools\devdiv\EcmaPublicKey.snk
System.Data.Linq f:\dd\tools\devdiv\EcmaPublicKey.snk
System.Web f:\RedBits\Tools\devdiv\FinalPublicKey.snk
Microsoft.VisualBasic f:\\RedBits\\Tools\\devdiv\\FinalPublicKey.snk

Nothing special, but... Keep this in mind when doing RTM so you don't something that shouldn't be distributed, like: CustomersIHate\Customer1\Key.snk

Wednesday, April 02, 2008 5:55:40 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 
 Tuesday, April 01, 2008

One thing that I like about SQL is the IN operator which checks if an argument is equal to any of the listed elements. C#/.NET doesn't offer this kind of operator which forces us to use code similar to the one below:

int i = 5;
if (i == 5 || i == 4 || i == 3)
{
    return;
}

Wouldn't it be better if we could just write like this:

if (i.In(5, 4, 3))
{
    return;
}

What we need is a simple Extension Method:

public static bool In<T>(this T source, params T[] values)
{
    return values.Any(v => v.Equals(source));
}

Few things to notice. First I'm using generic type parameter T to avoid boxing for Value Types. Second, it would probably be a wise thing to write few overrides like this:

public static bool In(this IComparable source, params IComparable[] values)
{
    return values.Any(v => v.CompareTo(source) == 0);
}

And another one for generic version. Finally it would be wise to provide an overload that accepts IEqualityComparer, like like LINQ extension methods do.

Whatever you do, you just have to love Extension Methods :-)

Tuesday, April 01, 2008 9:32:49 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  | 
 Saturday, March 29, 2008

There is a nice little base class hidden inside System.Collections.ObjectModel namespace. Its name is KeyedCollection. Its there to solve all those situations when we need a collection where items are to be unique, a "collection whose keys are embedded in the values" - as MSDN describes it.

As nice as the class is, there is one problem. It is abstract. The reason it is abstract is the GetKeyForItem method. For each type what we need a unique collection, we need to create a new class, inherit it from the KeyedCollection and override that one method. I think that's a bit of a waste of time and needles complexity in most cases. Fortunately, there is hope.

Enter KCollection. The idea behind it is to use Lambda Expressions where we had to override the GetKeyForItem method before. Sample code should explain everything:

class KCollection<TKey, TItem>  : KeyedCollection<TKey, TItem>
{
    Func<TItem, TKey> getKey;
    public KCollection(Func<TItem, TKey> getKey)
    {
        this.getKey = getKey;
    }
    protected override TKey GetKeyForItem(TItem item)
    {
        return getKey(item);
    }
}

And usage looks as follows:

KCollection<int, Client> kcol = new KCollection<int, Client>(c => c.Id);

Where Client is a simple class:

class Client
{
    public int Id;
    public string Name;
}

Of course we could achieve similar functionality using .NET 2.0 and delegates, I think Lambda Expressions are just nicer.

Saturday, March 29, 2008 2:44:47 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 

I've never liked VB.NET. Probably because I was (un)fortunate enough to work with VB6 for 2 years, even though .NET and C# were already there. Nevertheless I'm aware that VB.NET tends to offer some very useful syntax not found in C#.

One thing that I've recently discovered is the ability to specify a "Key Properties" when defining an Anonymous Type.

Syntax for the declaration is more or less as follows:

Dim person = New With {Key .Id = 1, .Name = "John"}

Notice the Key keyword before Id property. Now the interesting thing is that VB.NET compiler generates the Equals method that compares objects for equality, using only the Key Properties as opposed to comparing all properties when code is generated by C# compiler.

Now tell me that VB.NET is slower than C#.

More on the topic can be found on MSDN article on Anonymous Types in VB.NET, in section on Key Properties of course.

Saturday, March 29, 2008 11:59:11 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  |