Vadim's Weblog

Never stop learning.

Archive for July, 2008

How big is null in Nullable types?

Posted by Vadim on July 28, 2008

I use often Nullable types in my code.  However, when today I was debugging my code I was surprised to learn that the expression bellow equals to false:

   1: int? n1 = null;
   2: int? n2 = null;
   3: if (n1 <= n2)
   4:     Console.WriteLine("not going to happen");

I decided to dig deeper to see what the reason for this behavior.

I learned that when you have a Nullable type variable that is null (int? n1 = null) in relation comparison expression, the expression is always false.  By relation comparison I mean binary comparison with one of following operators: <, >, <= , =>.

Let me try to explain why this happens.   Let assume that we have two Nullable integers n1 and n2.  n1 is null and n2 has value of 5.  When you compare (n1 < n2), behind the scene the following comparison happens:

(
    (n1.GetValueOrDefault() < n2.GetValueOrDefault()) && 
    (n1.HasValue & n2.HasValue)
)

n1.GetValueOrDefault() will return 0.

n2.GetValueOrDefault() will return 5.

That means the first part of our expression will be true because 0 is less than 5.  However the second part of our expression will be translated into (false & true) which equals to false.  So the first expression is true and the second one is false that means that the whole expression is false too.

That explains why any relation comparison with null value will be false.

kick it on DotNetKicks.com

Posted in .Net, C#, Coding, Nullable Types | 1 Comment »

Jump between braces in Visual Studio.

Posted by Vadim on July 9, 2008

search_BraceHave you ever scroll, scroll, scroll to find the beginning of if else  statement?  In this post I’m not going to tell you that long methods and classes are evil.  Instead, I want to share with you how to move fast between open and close braces.

Put your cursor before or after the brace (your choice) and then press Ctrl+]. It works with either curly or round braces.  From now on you don’t need to play Where’s Waldo? to find that brace.

I’ve been using this trick since Visual C++ 4.0. 

kick it on DotNetKicks.com

Posted in Tips And Tricks, Visual Studio | 18 Comments »

Explaining GetHashCode method.

Posted by Vadim on July 5, 2008

Every object you ever created or used in .NET has GetHashCode method along with Equals, GetType, and ToString methods.  This method is an instance method of an Object class from which any other class derives.

GetHashCodeIntelisense

GetHashCode() method returns an integer that identifies an object instance.  I also can repeat MSDN documentation but you can read it on your own.

You would want to override this method along with Equals() method in your class if the object of your class is going to be used as a key in Hashtable.

The best way to explain it is to show an example. In I was using class Point as an example.  I’m going to continue with this class.  So let assume that we have class like this:

   1: public class Point
   2: {
   3:   private readonly int _x;
   4:   private readonly int _y;
   5:
   6:   public Point(int x, int y)
   7:   {
   8:     _x = x;
   9:     _y = y;
  10:   }
  11: }

Next we want to use Point as a key in a Hashtable.  Remember that the key of the Hasthable must be unique.  In the code bellow we have two identical keys (line 2 & 4). We should expect ArgumentException.

   1: Hashtable hashtable = new Hashtable();
   2: hashtable.Add(new Point(2, 3), "Point 1");
   3: hashtable.Add(new Point(5, 3), "Point 2");
   4: hashtable.Add(new Point(2, 3), "Point 3");

However, no exception was thrown.  There are two reasons why exception is not thrown:

  1. Equals() method that is also an instance method of Object class will always indicate that Point in line 2 and line 4 are different. This expected because two objects have different references.
  2. GetHashCode() method returns different number for these objects.

Try to execute code bellow:

   1: static void Main(string[] args)
   2:  {
   3:    var point1 = new Point(2, 3);
   4:    var point2 = new Point(2, 3);
   5:    Console.WriteLine("point1 Hash: {0}"
   6:         , point1.GetHashCode());
   7:    Console.WriteLine("point2 Hash: {0}"
   8:         , point2.GetHashCode());
   9:    Console.WriteLine("point1 equal to point2: {0}"
  10:         , point1.Equals(point2));
  11:  }

You will get output similar to this one:

point1 Hash: 58225482
point2 Hash: 54267293
point1 equal to point2: False

You can see that we got different hash codes.

To solve this problem we override Equal() and GetHashCode() in our Point class.

First we override Equals() method:

   1: public override bool Equals(object obj)
   2: {
   3:   if (ReferenceEquals(null, obj)) return false;
   4:   if (ReferenceEquals(this, obj)) return true;
   5:   return ((Point)obj)._x == _x && ((Point)obj)._y == _y;
   6: }

You can see that I use ReferenceEquals() method that is static method of Object class.  It checks if the specified objects are the same.

Next we override GetHashCode() method:

   1: public override int GetHashCode()
   2: {
   3:   unchecked
   4:   {
   5:     return (_x * 397) ^ _y;
   6:   }
   7: }

The whole Point would look like this:

   1: public class Point
   2: {
   3:   private readonly int _x;
   4:   private readonly int _y;
   5:
   6:   public Point(int x, int y)
   7:   {
   8:     _x = x;
   9:     _y = y;
  10:   }
  11:
  12:   public override bool Equals(object obj)
  13:   {
  14:     if (ReferenceEquals(null, obj)) return false;
  15:     if (ReferenceEquals(this, obj)) return true;
  16:     return ((Point)obj)._x == _x && ((Point)obj)._y == _y;
  17:   }
  18:
  19:   public override int GetHashCode()
  20:   {
  21:     unchecked
  22:     {
  23:       return (_x * 397) ^ _y;
  24:     }
  25:   }
  26: }

Now if you try to execute the application the output should look exactly like this:

point1 Hash: 793
point2 Hash: 793
point1 equal to point2: True

Also if we try to add new Point(2, 3) twice, we get an ArgumentException as expected.

kick it on DotNetKicks.com

Posted in .Net, C#, Coding, GetHashTable, VS2005, VS2008 | 13 Comments »

Comparing Reference Types in Unit Tests.

Posted by Vadim on July 3, 2008

If you’ve done some unit testing, you’re familiar with Assert.AreEqual method.  Have you try to compare two objects that have the same value(s) but the AreEqual method tells you that they are not equal?  For example let assume that we have a class Point:

   1: private class Point
   2: {
   3:   private int _x;
   4:   private int _y;
   5:  
   6:   public Point(int x, int y)
   7:   {
   8:     _x = x;
   9:     _y = y;
  10:   }
  11: }

And we test for the constructor:

   1: [Test]
   2: public void Point_constructor_test()
   3: {
   4:   Point point = new Point(2, 3);
   5:   Assert.AreEqual(point, new Point(2, 3));
   6: }

When I run this test using MbUnit, the assertion fails.  The reason it fails because Point is a reference type.     Actually what is getting compared is objects references (not objects values) and of course they have different references.

One way we could fix it is to make Point a Value Type by replacing class with struct.

   1: private struct Point
   2: {
   3:   private int _x;
   4:   private int _y;
   5:   
   6:   public Point(int x, int y)
   7:   {
   8:     _x = x;
   9:     _y = y;
  10:   }
  11: }

This definitely resolves the issue.

Another thing we could do is implement IEquatable<T> interface:

   1: private class Point : IEquatable<Point>
   2: {
   3:   private int _x;
   4:   private int _y;
   5:  
   6:   public Point(int x, int y)
   7:   {
   8:     _x = x;
   9:     _y = y;
  10:   }
  11:  
  12:   public bool Equals(Point other)
  13:   {
  14:     return (_x == other._x) && (_y == other._y);
  15:   }
  16: }

[Updated] However, MbUnit test still will fail because deep inside MbUnit’s AreEqual calls object.Equal(object).  In order for AreEqual to succeed in this case, it needs to call generic version of AreEqual.  Something like this:

   1: private static bool AreEqual<T>(T expected, T actual)
   2: {
   3:   if (expected is IEquatable<T> )
   4:     return ((IEquatable<T>)expected).Equals(actual);
   5:   return expected.Equals(actual);
   6: }

It means we need to modify our test little bit. Instead of AreEquals method we can use IsTrue one.

   1: [Test]
   2: public void Point_constructor_test()
   3: {
   4:   Point point = new Point(2, 3);
   5:   Assert.IsTrue(point.Equals(new Point(2, 3)));
   6: }

In software development the same problem can be solved many different ways.  I assume that most common solution is going to be comparing some public properties in the object instead of the whole object.

Let assume assume that our Point class has public properties X and Y.  Here’s an example how my test would look:

   1: [Test]
   2: public void Point_constructor_test()
   3: {
   4:   Point point1 = new Point(2, 3);
   5:   Point point2 = new Point(2, 3);
   6:   Assert.AreEqual(point1.X, point2.X);
   7:   Assert.AreEqual(point1.Y, point2.Y);
   8: }

kick it on DotNetKicks.com

Posted in .Net, C#, MbUnit, Reference Type, TDD | 3 Comments »

A faster way to lock your computer.

Posted by Vadim on July 1, 2008

I’m probably the last one to learn this key combination to lock computer.  Before this week, I was locking my computer by pressing three-finger salute (Ctrl-Alt-Delete) to launch Windows Security dialog and then press Enter key in order to lock my computer.  Starting this week I’ll be pressing only Windows Key + L.

I figure by pressing Win+L I’m going to save half a second per each instance.  Let assume that I lock my computer 6 times a day.  It means I’ll save 3 seconds a day and this adds up to about 18 hours minutes a year.

kick it on DotNetKicks.com

Posted in Tips And Tricks | 3 Comments »

Vista Start menu power button should Shut down.

Posted by Vadim on July 1, 2008

First time I tried to Shut down my brand new Vista, I pressed the Windows key on my keyboard and then clicked on the power button.powerButton

However, it just put my PC in sleep mode.  After that I’ve never used this button again until today.  By exploring Advanced settings in Power Options, I realized that I can configure this power button.

The easiest way is to press your windows key on your keyboard powerStartButtonand start typing power.   You should see Power Options in your Programs list.

Click on Power Options and Select a power plan window should be displayed on your screen.

This is a window where you can select your power plan.  Under each plan you can see Change plan settings link.  You should click on this link in order to navigate to Edit Plan Settings window.

EditPlanSettings_PowerOptions

We are not there yet.  Click on Change advanced power settings link, and you’ll see Power Options window.

Almost there. In the list section of that window extend Power buttons and lid and then extend Start menu power button.  In Setting change from default Sleep option to Shut down one.

PowerOptions

Press the OK button and you are finally done.  Now the power button is going to shut down Vista.

Also notice that before the power button was brown and now it’s reddish.

redPowerButton

kick it on DotNetKicks.com

Posted in Tips And Tricks, Vista | 3 Comments »

 
Follow

Get every new post delivered to your Inbox.