Tuesday, June 24, 2008

"Invalid URI: The Uri scheme is too long" - now that's a peculiar message. I got it while doing some Xslt transformations. It comes out that XslCompiledTransform can't just read any xml and transform it. There are issues if Uri scheme is too long. What is too long? Can't really tell, since mine wasn't THAT long.

The following code did not work for me:

XslCompiledTransform xsl = new XslCompiledTransform();
xsl.Load("t.xsl");
XmlWriter writer = XmlWriter.Create("dest.xml");
xsl.Transform(File.ReadAllText("source.xml"), writer);

So I had to use this one:

XslCompiledTransform xsl = new XslCompiledTransform();
xsl.Load("t.xsl");
using (XmlWriter writer = XmlWriter.Create("dest.xml"))
{
    using (XmlReader reader = XmlReader.Create("source.xml"))
    {
        xsl.Transform(reader, writer);
    }
}

The problem is the Transform method and File.ReadAllText that returns the whole source xml string at once. XslCompiledTransform just can't handle it for some reason.

Tuesday, June 24, 2008 9:01:05 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 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 [3]  | 
 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 [0]  | 

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 [0]  | 
 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 [1]  | 
 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 [1]  | 

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 [0]  | 
 Tuesday, July 03, 2007

Today I have found a really useful class inside the System.Diagnostics namespace. It's called DebuggerTypeProxy and it allows you to customize how you types behave (or more precisely what data do they present) inside the debugger.

Often I have overwritten the ToString method just to get my type look nice in the debugger. A common problem is when there is some kind of collection of objects and the only thing that you see when you look at it is the all of them are of a certain type. That's because of the default implementation of the ToString method. If you overwrite it to return - say a Name property of you Client object, you immediately have it easier when it comes to finding the concrete instance on the list. Although DebuggerTypeProxy won't help in making you types more easily visible on the list, it can do so much more!

Basically DebuggerTypeProxyAttribute is just what the name suggests - a proxy. It is a kind of view that you can assign to your types and debugger will use it much like DebuggerVisualizerAttribute is used to provide a custom view over a data type.

A simplest possible example to demonstrate how to use DebuggerTypeProxyAttribute:

[DebuggerTypeProxy(typeof(MyTypeProxy))]
class MyType
{
}

class MyTypeProxy
{
    MyType type;
    public MyTypeProxy(MyType type)
    {
        this.type = type;
    }
    public string Hash
    {
        get { return type.GetHashCode().ToString(); }
    }
}

And result of the code turns this:

Into this:

It is highly unlikely the you would ever need to create a type proxy to display it's HashCode, the example demonstrates a concept and that is: exposing method calls as properties. Normally debugger won't show you values that result from a method call. You can access them manually by calling methods in the Watch Window, Quick Watch Window or even Immediate Window. Using DebuggerTypeProxy you can achieve a more debugger friendly access to those results (if you ever need them).

kick it on DotNetKicks.com

Tuesday, July 03, 2007 5:51:40 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, June 18, 2007

With the release of .NET Framework 2.0, we have gained access to a very powerful feature called Anonymous Methods. I'm sure that almost any .NET developer has used Anonymous Method at least once and most of us use them on a daily basis.

Typically you use Anonymous Methods when you want to declare an event handler inline, without the need of creating a separate, named method (hence the name Anonymous). Other usage areas include delegates of types such As Predicate or Action. Mentioned delegates are most often used in methods found on all types of collection related classes be it Array or List<T>. Typical code for this may look like this:

string[] urls = GetUrls();
string[] urlWithWww;
urlWithWww = Array.FindAll(urls, delegate(string url) 
{ return url.StartsWith("www"); });

Nothing unusual here. The usefulness of Anonymous Methods comes from the fact that they allow us to access variables defined in the scope in which the very method is defined. Here as an example of how this feature is usually used:

string pattern = ".com";
string[] urls = GetUrls();
string[] urlWithWww;
urlWithWww = Array.FindAll(urls, delegate(string url) 
{ return url.Contains(pattern); });

Great feature indeed, but there is one gotcha that we have to be aware. The problem most often appears when we start to work with multiple threads. Given the following code:

foreach (string url in urls)
{
    DoSomethingAsync(delegate() 
    { 
        Debug.WriteLine(url); 
    });
}

We have to know that the url variable that we pass to a Debug.WriteLine method is "shared" among all Anonymous Methods and because of this, we may (and most probably we will) get results that we do not expect: same url printed few times, than a different url, again printed few times. Confusing, isn't it?

Why is that? Brad Adams explains the mechanism behind this strange behavior here (scroll down to the comments). It's worth mentioning that you could get the same strange behavior without working with multiple threads. It is just far more common to get it while theading.

To make things more "predictable", the code above has to be written in a slightly different way:

for (int i = 0; i < urls.Length; i++)
{
    string url = urls[i];
    DoSomething(delegate() 
    { 
        Debug.WriteLine(url); 
    });
}

Now every Anonymous Method gets its own copy of url and everything works as expected.

kick it on DotNetKicks.com

Monday, June 18, 2007 6:39:58 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Saturday, June 16, 2007

Today, while working with WebRequest (HttpWebRequest) class and its BeginGetResponse method I have discovered a strange behavior. It turns out that you cannot always relay on the IAsyncResult's AsyncWaitHandler's WaitOne method as I will try to show below.

The following is a more or less a standard way to work with an asynchronous web requests (code is simplified, all constructs such as using and try/catch and timeout handling have been omitted for simplicity reason):

class RequestState
{
    public RequestState(CompleteDelegate callback, WebRequest request)
    {
        Callback = callback;
        Request = request;
    }
    public CompleteDelegate Callback;
    public WebRequest Request;
}
private static WaitHandle MakeAsyncRequest(CompleteDelegate callback)
{
    WebRequest request = WebRequest.Create("http://vaultofthoughts.net");
    RequestState state = new RequestState(callback, request);
    IAsyncResult result = request.BeginGetResponse(GetResponseComplete, state);
    return result.AsyncWaitHandle;
}
private static void GetResponseComplete(IAsyncResult result)
{
    RequestState state = (RequestState)result.AsyncState;
    WebResponse response = state.Request.EndGetResponse(result);
    state.Callback();
}

Now we can invoke MakeAsyncRequest method from anywhere in our code passing a delegate that will be called upon request completion. We get a WaitHandle as a return value so we can synchronize threads in case multiple calls were made.

Where is the problem? Look at the following code:

private void MakeCalls()
{
    WaitHandle[] waitHandles = new WaitHandle[2];
    waitHandles[0] = MakeAsyncRequest(RequestComplete);
    waitHandles[1] = MakeAsyncRequest(RequestComplete);
    // Wait until both requests complete
    WaitHandle.WaitAll(waitHandles);   
}
private void RequestComplete()
{
    //....
}

The problem is that there is no guarantee that RequestComplete method will be called 2 times before code continues beyond the WaitHandle.WaitAll call. Why is that?

At first I thought it was a bug in how .NET threads work, but a while I have come to the understanding that it is the way it should be. The WaitHandles returned from the MakeAsyncRequest method are signaled as soon as the request completes. After request completes the GetResponseComplete method is called. At this time, WaitHandle is signaled. Only at the end of the GetResponseComplete method, the callback is called (it could even be called as the first action and it wouldn't make much difference).

So how to solve the issue? The solution is to return new instance of ManualResetEvent instead of IAsyncResult.AsyncWaitHandle. We also have to pass an instance of this object with rest of the state to GetResponseComplete method so we can signal it at the end, after the callback method is called.

A complete solution looks as follows:

class RequestState
{
    public RequestState(CompleteDelegate callback, 
WebRequest request, ManualResetEvent waitHandle) { Callback = callback; Request = request; WaitHandle = waitHandle; } public CompleteDelegate Callback; public WebRequest Request; public ManualResetEvent WaitHandle; } private static WaitHandle MakeAsyncRequest(CompleteDelegate callback) { WebRequest request = WebRequest.Create("http://vaultofthoughts.net"); ManualResetEvent waitHandle = new ManualResetEvent(false); RequestState state = new RequestState(callback, request, waitHandle); IAsyncResult result = request.BeginGetResponse(GetResponseComplete, state); return waitHandle; } private static void GetResponseComplete(IAsyncResult result) { RequestState state = (RequestState)result.AsyncState; WebResponse response = state.Request.EndGetResponse(result); state.Callback(); state.WaitHandle.Set(); }

I have marked the changed parts in the code above. Notice that we don't have to change the code that is using our method.

kick it on DotNetKicks.com

Saturday, June 16, 2007 6:58:09 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, June 15, 2007

Today I was working with System.Uri class a bit and I must say that it is very useful. Just imagine checking if a given URL is absolute or getting the host name from URL or even getting the query part. All of this is implemented in this one class by means of properties like IsAbsoluteUri, Host, Query etc. There is however one problem...

While playing with System.Uri I encountered a situation where while trying to create an Uri object I got the following exception:

System.UriFormatException was unhandled
  Message="Invalid URI: The format of the URI could not be determined."
  Source="System"
  StackTrace:
       at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
       at System.Uri..ctor(String uriString)

Of course there is nothing wrong with it. Not every string represents an Uri. So, remembering about the pattern found in classes such as Boolean or Int32 I looked for a TryParse method. As it came out, System.Uri doesn't have a TryParse method but there is TryCreate method instead. After changing the code to use TryCreate method and running the application it came out that I still have a problem somewhere.

At first I thought that the problem was the TryCreate method! In all cases where the normal constructor failed for me, the TryCreate method not only returned true, but also constructed a System.Uri object!

The following code demonstrates the issue:

string url = "asdasda";
Uri uri;
if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri))
{
}
else
{
    uri = new Uri(url);
}

The above code should run smoothly, but it will throw the mentioned System.UriFormatException. The reason for this is that when using the constructor, we should also use the overload that allows us to pass the UriKind as an argument!

Friday, June 15, 2007 8:11:15 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, May 28, 2007

From time to time I have to create a form that is used both for display and input of data (or in other words for viewing or adding/editing). As an example, imagine a form for entering customer data. The form will include fields such as Name, Address etc. There are few possible solutions to this problem.

First and most easy to implement is to create a single form, put required input controls on it: one TextBox for Name and one for Address. When constructing the page on the server, we have to check if the form is used  in View mode in which case we have to set the controls' ReadOnly property to true. Otherwise we can leave it as false. ASP.NET controls mostly support this kind of mechanism. The problem is that a ReadOnly TextBox is still rendered as HTML input control. You can try to hide the fact by using CSS styles, but underneath it is still an input control for a form that does not require one.

Another solution I have seen used a lot is to create a separate page used only to display the date and another page for editing/adding data. In this case, the page used to display data uses controls such as Label control so no input field is generated. The other page works as can be expected. The problem with this solution is that now we have two pages and some of the logic/layout/whatever is duplicated.

ASP.NET architecture to the rescue! Since ASP.NET is designed in such a way that it makes heavy use of controls, we can take advantage of the fact and introduce a special kind of TextBox control that is intelligent in a way it renders itself.

The way to achieve this goal is simple. Create a new Class, make it inherit from the TextBox control and override few methods:

public class TextBox : System.Web.UI.WebControls.TextBox
{
    [DefaultValue(false)]
    public bool RenderReadOnlyAsText
    {
        get { return (bool)(ViewState["RenderReadOnlyAsText"] ?? false); }
        set { ViewState["RenderReadOnlyAsText"] = value; }
    }
    protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
    {
        if ((!RenderReadOnlyAsText) || (!ReadOnly))
        {
            base.AddAttributesToRender(writer);
        }
    }
    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        if ((RenderReadOnlyAsText) && (ReadOnly))
        {
            System.Web.UI.WebControls.WebControl span = 
            new System.Web.UI.WebControls.WebControl(System.Web.UI.HtmlTextWriterTag.Span); span.RenderBeginTag(writer); writer.Write(Text.Replace(Environment.NewLine, "<br />")); span.RenderEndTag(writer); } else { base.Render(writer); } } }

Notice the RenderReadOnlyAsText property which is false by default making the new control behave just like a normal TextBox. Next we need to override the Render method. I have used span control to replace the normal input control, but feel free to experiment. The thing to remember is to replace the NewLine characters with HTML line breaks (probably some CSS style would also do). Additionally I have overridden the AddAttributesToRender method so that it does not add any attribute to the control in case it is rendered as a plain text (or span in my case).

Using this control on a page is simple. Just set the RenderReadOnlyAsText to true and set ReadOnly property to true when necessary.

kick it on DotNetKicks.com

Monday, May 28, 2007 4:34:05 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, February 14, 2007

Introduction of Nullable<T> was a great thing that many of us have been waiting for for a long time. One of the benefits is the implementation of lazy loaded properties.

There are however few gotchas that you have to be aware of. Something that surprised me the most was the implementation of the ToString method:

public override string ToString()
{
    if (!this.HasValue)
    {
        return ""
    }
    return this.value.ToString();
} 

What is unusual with it? Given the following code:

int? i = null;
string s = i.ToString(); 

What would you expect to happen? I would expect a NullReferenceException to be thrown. After some thinking though, I'm not so sure anymore. If we take into consideration a fact that ValueTypes are not ReferenceTypes i.e. there is no reference to a ValueType unless it is boxed, than having no NullReferenceException is perfectly legal and obvious in the described scenario.
The ToString implementation above clearly fulfils this assert so there will be no NullReferenceException even if Nullable value is null.
Is it good or bad? Now when I know about it, it doesn't really matter that much for me, but I was very surprised nonetheless. I think though that since null is not really null in case of ValueTypes, maybe there should only be a HasValue property? That would however made using Nullable types a lot more cumbersome... Nothing is ever easy :-).

kick it on DotNetKicks.com

Wednesday, February 14, 2007 11:28:17 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, January 31, 2007

During my investigation of how and what of AutoGenerateColumns in GridView in my recent articles, I had a need to check if a type is a Nullable type. I have used reflector to search for a siutable method, but I haven't found one. What I have found though was a strange class: System.Internal. It is internal so it is not accessible outside its assembly, but nevertheless I find it worth mentioning because of its contents.

The class has 3 methods that make me think:

  • CommonlyUsedGenericInstantiations_HACK()
  • NullableHelper_HACK<T>()
  • SZArrayHelper_HACK<T>()

Just by looking at the names I can tell that there is something about them, that is not your usual BCL code :-)

When I have looked inside the first one of those methods I have found a lot of code that only instanties Generic type objects such as List<T> where T is bool, int, Guid etc. The second method on the other hand calls Compare<T> and Equals<T>.

Why is that? In my opinion, all the operations there are perfoemed to improve performance of some code. By doing the operations in a batch, once, at some point in time, we do not risk the JIT compiler compiling every generic class and every generic method on demand later. If this really helps or is useful? I don't know, but MS has done it and I usually do not believe in "random code". Maybe there are some performance considerations in some scenarios that require the HACK approach? I haven't been able to find a place in the BCL that uses the System.Internal class.

kick it on DotNetKicks.com

Wednesday, January 31, 2007 2:37:13 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
 Friday, January 12, 2007

The "as" operator as described in MSDN is an operator: "Used to perform conversions between compatible reference types". We have to keep this in mind when coding. Often it is just easier (and it looks nicer too) to use an "as" operator instead of a cast, or when we want to handle the DBNull value returned from the database like in the following scenario:

string s = reader["Name"] as string;

instead of

string s = (string)((reader["Name"] is DBnull) ? null : reader["Name"]);

Assuming that the name column can be null in the database.

When we use it we accept that something could be of incompatible type such as Name column being of numeric type return. What happens then? What happens if the column type has changed? In the scenario above, we will always get a null reference, which in a worst case scenario we will discover very late in project.

Of course in some situations it is just what we need. What I have found however is that misusing the "as" operator can often lead to unexpected NullReferrenceException exceptions being thrown (or worse yet nothing wrong happens at first). If you find that happening it may mean that you are using "as" operator as a shortcut where an ordinary cast would be in place. Using a cast often causes bugs to appear sooner in the development life cycle which is always a nice thing. So basically a rule of thumb is to always think twice whether to use a cast or an "as" operator.

kick it on DotNetKicks.com

Friday, January 12, 2007 12:17:26 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 

Since the beginning of my adventure with .NET I have always asked myself one question: why do we need the DBNull type? Is a simple null reference not enough?
MSDN says that DBNull "Represents a nonexistent value". From a logical point of view - this one sentence explains why a null reference cannot be used - because it is a null reference and not a lack of value. But is it enough to introduce a type that causes a lot of trouble?

DBNull is typically used in ADO.NET when returning data from the database. If one column does not have a value in the database, it will be represented as a DBNull object. That is something altogether different from what I would expect at the domain level. When working with objects when there is a Client object, and I ask for his Name then if the name is not there I expect to get null in return. It is very natural to me and probably to most of the developers. When we need to interact with data layer that is where most of the problems with DBNull kick in.

Consider a simple example of a Client's Name property which is of a String type. In your code you accept a situation when the Name is null which may mean that it has never been set. When you save such a Client to a database using a simple Insert call, everything works OK. (it was in fact my data access library that handled null inserts by changing them to DBNulls) You check the database and the data is in fact there and the Name is "null". When next time you try to get the Client from the database, you have to read all the columns and put the values into your object like in the following example:

Client c = new Client();
c.Id = (Guid)row["Id"];
c.Name = (string)row["Name"];
...

This will result in an InvalidCastException exception being thrown with a message "Unable to cast object of type 'System.DBNull' to type 'System.String'." That is of course because null values from the database are represented as DBNull objects.

Typical solution for this problem is to check the column for DBNull before casting or using an "as" operator which you have to be carefull with as I describe in another post.

Whichever way you choose, what you get is an overly complicated code that does a simple thing!

I don't think that the sentence from MSDN that describes the purpose of DBNull is a good excuse for introducing DBNull type. I don't think that returning null instead of DBNull would cause any loss of information. What I think is that DBNull should have never been introduced because it makes developer's work harder without adding any real value. Additionally ADO.NET is inconsistent in that it allows saving a null referrence to a database but does return DBNull instead. Because of the fact that I don't like to deal with DBNulls, in my data access library, I'm always replacing it with a null reference so I never get it to propagate to the upper layers. That way I get a better separation from a database level stuff.

BTW: If anyone has something to say in defense of the DBNull I woulreferenced gladly hear it.

kick it on DotNetKicks.com

Friday, January 12, 2007 12:08:55 AM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [8]  | 
 Thursday, January 04, 2007

There is a very useful class in the .NET framework that allows you to cancel an event from the handler perspective. This class is the CancelEventArgs. Typically using this class looks as follows:

event EventHandler<CancelEventArgs> Click;
void OnClick()
{
    CancelEventArgs e = new CancelEventArgs();
    Click(this, e);
    if (e.Cancel)
    {
        // do nothing
    }
    else
    {
        // do something
    }
}

void ClickHandler(object sender, CancelEventArgs e)
{
    if (something)
    {
        e.Cancel = true;
    }
}

BTW: I have no idea why Microsoft defined CancelEventArgs under System.ComponentModel namespace.

Simple and easy. But there is a problem. What if there was a second handler for the Click event?

void ClickHandler2(object sender, CancelEventArgs e)
{
    e.Cancel = !IsValid();
}

In some scenarios, the ClickHandler2 would override changes made by ClickHandler - i.e. it would set Cancel property to false in case the state was Valid. I strongly discourage you from ever setting Cancel property to false! The problem is that in the handler method you never know if you are the only one handler or are there more handlers involved! If a previous handler had already cancelled the event you will lose this information!

In order to prevent potential mistakes, I propose an alternative version of CancelEventArgs. The version that will prevent you from making a mistake. Below is a how such a class could look like:

class CancelEventArgs : EventArgs
{
    bool cancelled;
    public bool Cancelled
    {
        get { return cancelled; }
    }
    public void Cancel()
    {
        cancelled = true;
    }
}

Notice that the Cancel property is now called Cancelled and is read-only. To Cancel an event you use the Cancel method which works only one way - there is no way to accidentally set Cancelled to false. The safer, the better :-)

kick it on DotNetKicks.com

Thursday, January 04, 2007 10:34:37 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  | 
 Thursday, November 23, 2006

Today I have recieved a comment on my article on Optimizing Rendered Page Size, that it is not possible to override the LoadPageStateFromPersistenceMediummethod of a Page class because it is marked as internal in ASP.NET 2.0. Strange thing was that I have made just that in one of the projects I have been working on with ASP.NET 2.0! So I went for some searching.

First thing I have checked the code to see if it really compiles with the override - it did. There is even a support from Intelisense for overriding this method. Next I want to see if the is LoadPageStateFromPersistenceMediummethod really internal. Using reflector I have been able to confirm this. It really is "protected internal virtual". So the question is: how am I able to override it?

The reason we are able to override such a method is that "protected internal" is an OR relationship which means that such a member is accessible in the types that derive from our type AND in all types defined in the assembly. This should make it clear why we are able to override this method.

What may be less clear is why overriding "protected internal" requires sometimes "protected override" instead of "protected internal override". If you read once more the definition, it clearly states that protected internal is accessible to sub-types and the assembly. So if you want to override a method in the same assembly you would use "protected internal override". If on the other hand you want to override this method in other assemblies you must not use the "internal" access modifier because it would make the method visible to every type in your assembly - which would in fact change the visibiliti of the method. This would of course result in an error from the compiler. In this case you would get the CS0507 error.

I hope this sheds some light on the issue.

kick it on DotNetKicks.com

Thursday, November 23, 2006 2:15:34 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 

Following my last article on IComparable vs IComparer interfaces I now present a common pattern that I have found to be very effective in terms of code usability.

In order to make working with IComparer implementing classes more natural and intelisense friendly I usually create the inner classes of the main class and expose the objects as as static properties or methods. The following example demonstrates:

public class Person
{
  int age;
  string name;
  public static IComparer<Person> GetPersonAgeComparer()
  {
    return new PersonAgeComparer();
  }
  public static IComparer<Person> GetPersonNameComparer()
  {
    return new PersonNameComparer();
  }
  private class PersonAgeComparer : IComparer<Person>
  {
    #region IComparer<Person> Members
    public int Compare(Person x, Person y)
    {
      return x.age.CompareTo(y.age);
    }
    #endregion
  }
  private class PersonNameComparer : IComparer<Person>
  {
    #region IComparer<Person> Members
    public int Compare(Person x, Person y)
    {
      return x.name.CompareTo(y.name);
    }
    #endregion
  }
}

Now when you need to sort a collection of Person objects you just get the right IComparer from the Person's static Get*Comparer methods. Notice that the IComparer classes are defined as private so the only way to create them is through the factory - like static method. Making the classes private is nice a way to prevent Intelisense from unnecessary displaying them when what we really need is the concrete object. Notice the use of generic interface, which is new to the .NET Framework 2.0. You could also use the partial classes feature to put the comparers in a separate file if necessary.

kick it on DotNetKicks.com

Thursday, November 23, 2006 1:25:33 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, November 22, 2006

In .NET some of the collection types such as Array, ArrayList, List<T> expose the Sort method that allows you to sort the collection. In order for those classes to sort the collection, there has to be a way for them to somehow compare objects with each other. The most basic Sort method usually does not require any arguments other than the collection itself in case of the static Array.Sort. In this case how does the framework know how to compare our objects? Is person1 greater than person2? Or maybe they are equal?

Enter the IComparable interface. By implementing this interface, the objects of the type become, as the name suggest, comparable, so now it is possible to compare person1 to person2 using a simple person1.CompareTo(person2) call. With this each Sort method can easily handle sorting. An example implementation of sort method is included in the MSDN documentation.

So what is wrong there? If you take a Int32 objects, a String object, the IComparable interface on those is pretty straightforward and self explaining. It is plain even to a non-technical person that 1 < 3 and "abc" = "abc". But what about a more complex types such as a custom Person type that represents a person in the real world.

What does it mean for one persons to be greater (or equal for that matter) than the other? It does not mean anything without a context, a criteria by which we compare the two. So for example if were to compare the age of both persons, we would be able to say if who is older (greater) or younger (lesser). We could compare their names, their salary or whatever, but we need to know the criteria before we start.

Suppose that we have a class definition of Person as follows:

public class Person : IComparable
{
  int age;
  string name;

What does it mean for an object of this class to be comparable to each other? Is the name used? Or maybe the age? The fact that we don't know! The only way to know is to check the documentation or the implementation of the CompareTo method. First one goes against the rule I like to follow that states that the code should be self documenting. In this case it isn't. The second option breaks the rule of encapsulation - that is, we have to know the implementation of an object to work with it. Fortunately there is another way to compare and sort objects.

Enter the IComparer interface. This interface allows you to compare two objects in a similar way the IComparable interface does. The difference here is that it IComparer allows for much greater expressiveness. An implementation of IComparer is always a class which does have a name. This name explains (or at least it should) exactly what it does. For example:

public class PersonAgeComparer : IComparer

Makes it obvious to everyone what will be the criteria for the comparison without breaking the encapsulation. This makes your code easier to understand and much more self documenting. I strongly discourage everyone from using the IComparable interface on classes where it is not explicit what would be compared, even if it will be the only comparison made.

kick it on DotNetKicks.com

Wednesday, November 22, 2006 7:48:06 PM (Central European Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, October 23, 2006

For a long time now I have been wondering how to handle a situation in which there is an unhandled exception thrown from the event handling method of my events. Given the simple pattern for raising events in the form of:

private event EventHandler SomeEvent;
protected void OnSomeEvent()
{
   
if (SomeEvent != null)
   {
      SomeEvent();
   }
}

What happens when one of the handlers of SomeMethod throws exception? Keeping in mind the internal implementation of events that I have described here, I know that this exception will go outside the SomeEvent() call and even outside the OnSomeEvent() up the call stack. It is rather obvious. What is not so obvious is one should handle such a situation?

I have spend some time searchin the Internet for some kind of guideline or best practice but I have been unable to find one. I have talked with Krzysztof Cwalina about it and it seems that there is no good solution to the problem. You can put the event invocation in the try catch block but the only kind of exception you can catch there is really the Exception - since you don't know anything about what the handler may be. Krzysztof suggests that it may be good idea to document what kind of exception you expect from the event handlers but it it only a partial solution. Other solutions include terminating the application, allowing the exception to propagate or swallowing the exception - none of those seems right to me.

If any of you knows of any proven practice on how to handle this kind of situation I would really appreciate it if you point me in the right direction.

kick it on DotNetKicks.com