The .NET blog

New articles on Reflection

November 13, 2008

Just a small note to let you know that a set of chapters about Reflection has been added to the C# tutorial. You can find the introduction right here. I simply love using Reflection, so I’m probably going to write some more on it in the near future - anything specific you would like me to look into? I’m all ears :)

Filed under: C#, General — admin @ 10:35 pm

Sorting items in a generic List<T>

October 27, 2008

Generic lists were introduced in .NET 2.0, and I have been a big fan of them ever since. I used to use the ArrayList class, before .NET 2.0, but the List<T> has the major advantage of being strongly typed, which is cool because the compiler will let me know if I’m trying to add another type than the one specified. When .NET is aware of which type of objects are in the list, everything becomes much faster too, because no boxing is required when adding and pulling items from the list.

This post is about sorting your generic lists, mainly because I do it all the time, and it’s actually quite easy, once you understand how it works. The Sort() method on a generic list has 4 overloads, and since the first one doesn’t take any parameters at all, it’s by far the easiest one to use :). Here is an example:

List<string> list = new List<string>();
list.Add("Tom Hanks");
list.Add("Al Pacino");
list.Add("Mel Gibson");
list.Sort();
foreach(string name in list)
    Console.WriteLine(name);

We simply create a new list, add some names to it, call the Sort() method and then we output the list to the console. If you try the example, you will see that the items get sorted just perfectly - but how? Because the String object has a CompareTo() method that will do all the work, and since the compiler knows that the list will contain strings only, it can safely compare each item using the CompareTo() method of the string class. You can try changing the list type to a List<int> and add numbers to it instead - it will work like a charm! However, this was a simple example. In a lot of situations, you will be using the List<T> to store your own types in, and .NET won’t necessarily know how to sort them. Look at this example:

public class Person
{
    private string firstName;
    private string lastName;
 
    public Person(string firstName, string lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
 
    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }
 
    public string LastName
    {
        get { return lastName; }
        set { lastName = value; }
    }
 
    public override string ToString()
    {
        return this.firstName + " " + this.lastName;
    }
}

If you create a new List<Person> and add some persons to it and try to call the Sort() method, you will get the following error:

Failed to compare two elements in the array.

Why? Because .NET has no idea how you want this new and strange type sorted. Fortunately, it’s easy to fix. I usually prefer doing it by letting my classes implement the IComparable interface:

public class Person : IComparable
{
    ...
 
    public int CompareTo(object obj)
    {
        if(obj is Person)
            return this.LastName.CompareTo(((Person)obj).LastName);
        else
            return 0;
    }
    
    ...
}

The CompareTo method is rather simple: It returns 0 if the two compared items are identical, and -1 or +1, based on which item is considered “bigger”. In this case, we simply take advantage of the fact that the String class has a CompareTo method, and then return the result of comparing the current object’s LastName property to the LastName property of the object passed in through the argument (obj). Try running the code now, and you should see the list get sorted by the persons last names. Now, if you wish to sort in the reverse order, you simply use the CompareTo() method on the obj instead of on this:

return ((Person)obj).LastName.CompareTo(this.LastName);

If you don’t want to, or can’t, implement the IComparable interface on the target class, you can do it “on the fly” by passing a delegate to the Sort() method. Here is a complete example:

List<Person> list = new List<Person>();
list.Add(new Person("Tom", "Hanks"));
list.Add(new Person("Al", "Pacino"));
list.Add(new Person("Mel", "Gibson"));
list.Sort(delegate(Person p1, Person p2) { return p1.FirstName.CompareTo(p2.FirstName); });
foreach(Person p in list)
    Console.WriteLine(p.ToString());

It might seem a bit faster and simpler, but it does require you to either write this delegate each time you use it, or declare it somewhere and pass it to the Sort method. Letting the objects them self do the comparing is probably a more clean solution, but not always possible. Hopefully this covers all your sorting needs :)

Filed under: C# — admin @ 12:32 am

Using the using statement

September 19, 2008

With .NET we have the garbage collector to clean up all the mess we make through the lifecycle of an application. But does that mean that we will never have to clean up anything our self? Not really. As a general rule, classes which implements the IDisposable interface should be manually disposed, usually by calling a Close() or Dispose() method on the instance. It could look a bit like this:

StreamReader sr = new StreamReader(@"C:\temp\myfile.txt");
while(!sr.EndOfStream)
{
        Console.WriteLine(sr.ReadLine());
}
sr.Close();

As you can see, we call the Close() method in the end - if we don’t do that, an unmanaged reference to the file will be kept open, which is something we really don’t want. However, you might have lots of lines of code working with the file, and in the end, you forget to dispose of the object. The using statement in C# can help prevent this, and also comes with another benefit, explained after this example of using it:

using(StreamReader sr = new StreamReader(@"C:\temp\myfile.txt"))
{
    while(!sr.EndOfStream)
    {
        Console.WriteLine(sr.ReadLine());
    }
}

As you can see, there are no explicit call to the Close() method - the using statement takes care of it for us. Since it has its own scope, the .NET framework knows that once this scope ends, the object(s) declared in the using statement can be disposed. You can even have several using statements for one block, like this:

using(Pen p = new Pen(Color.Black, 2))
using(SolidBrush sb = new SolidBrush(Color.Red))
{
    // Do stuff with p and sb here
}

As mentioned, the using statement comes with another advantage: It works as a try..finally block too! In the first two examples, an exception could easily occur, because we were dealing with files and doing no error checking at all. In the first example, an exception would cause the execution of the code to end, and the reference to the file would not be closed! This could be solved by creating the file reference within a try block, and then calling the Close() method in the finally block, but in fact, the using() statement does just that for us automatically, meaning that you can be sure that objects instantiated in a using statement will be disposed, no matter what!

So in conclusion: Use the using statement! :)

Filed under: C# — admin @ 10:28 am

Testing on different machines

September 14, 2008

In case you haven’t noticed, testing your applications on several machines is a very good idea, especially in that pre-beta phase, where you want to get rid of the most obvious bugs before showing your work for the first time. Especially with the .NET framework, testing your work on other machines than the one it’s being developed on is recommendable. You could easily have forgotten to include a specific assembly, or include an older version than the one you are currently using. Another common pitfall is to develop on Windows XP, and not testing on Windows Vista. A lot of things have changed, and some of them may break your application. And it goes the other way too - in my experience, several things which will work just fine on XP, will not work as well on a Windows 2000 machine.

Now, don’t go out and buy 2-3 new computers, with different OS’ on them. This scenario is perfect for the Virtual Machine. Many people swear by vmware, which is supposed to be really good, but personally I just use Microsoft Virtual PC 2007. With version 2007, it can now be downloaded and used for free, and in my experience, it’s very stable and extremely easy to use.

The absolute top feature of a virtual machine for software developers, is the undo disk feature. It allows you to boot the VPC, work on it, and then delete all changes. This gives you the possibility to test your application on a clean machine each time. Once you have installed a version of Windows in your Virtual PC, select it from the list and click Settings. Now, from the list of options, select Undo Disks and make sure that it has been enabled. Now, boot the OS, make it comfortable for you to work with (for instance, I always enable the display of file extensions, because I hate not being able to see them) and visit Windows Update and make sure that it’s fully updated. Once you close the system, make sure that you commit the changes to disk. You now have a fully functional test OS, and whenever you use it for testing purposes, just make sure that the “Commit changes to disk” is not checked, and the changes you have made will not be persisted. You may still choose to save changes from session to session, but it will be stored separately, and only committed to your VPC if you want it to - if not, simply select the delete option upon closing the OS.

With a setup like this, you have clean and mean testing environment for your applications :)

Filed under: General — admin @ 11:21 am

Creating and filling strings of a certain length

September 9, 2008

Sometimes, you need a string of a certain length, filled with a certain character, usually whitespace. I use it quite a bit, to replace a certain piece of text with an equal amount of whitespaces. But if all you have is the fill character and a desired length, how do you get a proper string? In a lot of languages, you would have to use e.g. a for-loop to loop X number of times and append to a resulting string, but not with the .NET framework. The String class comes with a constructor which allows you to accomplish the above very easily. Here is an example:

string whitespace = new String(' ', 10);

Or perhaps you need something that will look like a password?

string password = new String('*', 8);

Just another one of those small things that makes the .NET framework such a pleasure to work with.

Filed under: C# — admin @ 10:56 am

Installing the .NET framework along with your application

September 2, 2008

One of my biggest concerns when starting to build .NET applications, was the lack of framework installations around the world. Microsoft were promising to push it through Windows Update and Windows XP SP2, but that part didn’t really work for them until Windows Vista was released, which included both .NET 2.0 and .NET 3.0. However, since there are still quite a few Windows XP machines out there, and even worse, Windows 98 and Windows Me machines, you really can’t expect everyone to have the required version of the .NET framework installed.

One alternative is to use an expensive product which will bundle your application together with at least parts of the framework, but it usually IS very expensive, and it will result in a pretty big file, which you have to distribute. That might be good enough in your scenario, but for me, I wanted to be able to distribute only my own files.

If you’re using a very fancy installer, it might support the installation of the .NET framework from the beginning, but personally, I use the very neat and very lightweight Inno Setup. It’s free, easy to use, it supports command line operations, has a lot of options and a scripting language for you to extend your setups with, and it produces fast and very well compressed EXE setup files. I really do recommend it.

Since Inno Setup supports scripting, this guy Andrew made a very cool extension, which will automatically download and install the .NET framework to the clients computer, if it’s not already present. You can read more about it here and find the mentioned script here. I think that it’s a very elegant solution to a problem that a lot of .NET developers will face, while we still wait for the framework to be present on every computer in the world :)

Filed under: General — admin @ 11:51 am

Hello, world!

September 1, 2008

Welcome to the blog here at net-tutorials.com. We hope to provide you with some insightful posts in the near future. My initial thoughts are to use this space for tips & tricks, news and just pretty much everything .NET related I can come up with. If you wish to contribute, please leave a comment :)

Filed under: General — admin @ 10:38 pm



© net-tutorials.com 2006 - 2008