Sunday, March 2, 2008

Custom ORDER BY in SQL

.NET provides very useful techniques for custom ordering, e.g. generic comparison delegate, lambda expressions, IComparable interface etc.

When the sort order is needed at database layer, you can use the following statement:

SELECT *

FROM ContestParticipants

ORDER BY

CASE result

  WHEN 'winner' THEN 1

  WHEN 'loser' THEN 2

  WHEN 'dnf' THEN 3

  ELSE 4

END



kick it on DotNetKicks.com

Monday, January 14, 2008

How to Test Private Fields and Methods using NUnit

When you write unit tests, you need call some methods and compare their results with expected values as well as check overall state of objects through fields and properties. It is good to separate tests from testing code. But, what about testing private fields and methods? In addition, tests may be in a standalone assembly. Have a look at the possible ways:











everything is publicBreaks API
private -> internalKeeps API, but tests must be in the same assmebly
private -> internal, InternalsVisibleToAttributeKeeps API and tests may be in separated assembly


The last way is the right one. internal modifier is clear. Be careful about protected fields, their modifier should be protected internal. All members are visible within the scope of assembly, but tests are in a separated assembly. What now? The InternalsVisibleToAttribute comes in handy.

InternalsVisibleToAttribute is supported in .NET framework 2.0 and higher. This attribute specifies the "friend assembly" - assembly, that has access to all internal members. So, the last one step is to add the following line to AssemblyInfo.cs file:

[assembly: InternalsVisibleTo("FriendAssemblyName, PublicKey=...")]



kick it on DotNetKicks.com

Monday, November 12, 2007

Faster Device Emulator in Visual Studio 2005

Hurray! There is a new and faster Device Emulator in Visual Studio 2005. Deployment and debugging of .NET Compact Framework apps used to be very slow and tiring. Some bugs were fixed and deployment is significantly faster in Device Emulator ver. 2.0 (download here). Installer will replace the old version in your Visual Studio.

Friday, September 21, 2007

Boxing Mystery in Overloaded and Overridden Method

Recently I have produced a code with strange behaviour in my real C# project. Look at this code:

class BaseMystery

{

  public virtual void Foo(int i) { }

}

 

class Mystery : BaseMystery

{

  private void Foo(object i)

  {

    Console.WriteLine("Finished.");

  }

 

  public new void Foo(int i)

  {

    Foo(i);

  }

}

 

static void Main(string[] args)

{

  Mystery mystery = new Mystery();     

  mystery.Foo(3);

}


It produces:

Process is terminated due to StackOverflowException.


There is nothing strange. The method Mystery.Foo(int) is called repeatedly. Then I replaced hidding method Mystery.Foo(int) by overriding method:

class BaseMystery

{

  public virtual void Foo(int i) { }

}

 

class Mystery : BaseMystery

{

  private void Foo(object i)

  {

    Console.WriteLine("Finished.");

  }

 

  public override void Foo(int i)

  {

    Foo(i);

  }

}

 

static void Main(string[] args)

{

  Mystery mystery = new Mystery();     

  mystery.Foo(3);

}


And the output is:

Finished.


Hah! What is the matter? Let us go to explore IL code of method Mystery.Foo(int):

public new void Foo(int)


.method public hidebysig instance void Foo(int32 i) cil managed

{

  .maxstack 8

  L_0000: nop

  L_0001: ldarg.0

  L_0002: ldarg.1

  L_0003: call instance void BoxingMystery.Program/Mystery::Foo(int32)

  L_0008: nop

  L_0009: ret

}


and

public override void Foo(int)


.method public hidebysig virtual instance void Foo(int32 i) cil managed

{

  .maxstack 8

  L_0000: nop

  L_0001: ldarg.0

  L_0002: ldarg.1

  L_0003: box int32

  L_0008: call instance void BoxingMystery.Program/Mystery::Foo(object)

  L_000d: nop

  L_000e: ret

}


Argument i has been boxed. Why? I would expect that the IL body of method Mystery.Foo(int) will be the same in new and override declaration but it is different. It is very strange behaviour of compiler. What is your explanation?

Overridded method in my real project was the right one. In addition, I renamed the methods, because my colleagues could be confused like me.

kick it on DotNetKicks.com

Monday, September 17, 2007

Launch NUnit Tests directly from Visual Studio and Debug

Launching tests directly from Visual Studio is very comfortable feature. Developers, who are familiar with test driven development, need to launch tests frequently, so this feature is necessary for them.

My favourite testing framework is NUnit. Tests in this framework are launched from external application with perfect GUI.

In this article I will demonstrate how to start external application from Visual Studio, e.g. NUnit GUI, and keep running debugger. Debugging NUnit tests is very significant advantage because standard GUI of NUnit framework does not support it.

So, suppose that you have created a class library project with the following NUnit test:

using System.IO;

using NUnit.Framework;

using NUnit.Framework.SyntaxHelpers;

 

namespace DirectNUnit

{

  [TestFixture]

  public class Tests

  {

    [Test]

    public void Test()

    {

      string combinedPath = Path.Combine(@"C:\Projects", @"HelloWorld");

      Assert.That(combinedPath, Is.EqualTo(@"C:\Projects\HelloWorld"));

    }

  }

}



Now, you want to start this test directly from Visual Studio and use some breakpoints in the test. You can do it without any VS plug-in, just edit project settings. Open Project | Properties | Debug and set values like this:



Enter Start external program and Command line arguments, that is the path to the assembly containing your test.

For launching NUnit GUI and debugging tests press F5.

kick it on DotNetKicks.com

Monday, June 11, 2007

Currency Format Depending on Culture

It is usual, that you write an application with GUI for a specified culture and then you suddenly get to know that the application should work with several different currency formats. In the following example I want to demonstrate a very simple method how to change the currency format in your application elegantly and dynamically.

Ordinarily numbers are formatted as currency by these ways:

decimal value = 1234567.89M;

Console.WriteLine(value.ToString("C"));

//or

Console.WriteLine("{0:C}", value);

//or

Console.WriteLine(String.Format("{0:C}", value));


Actually, there are many places like this in your application and you want to change the format depending on user's choice of culture. The following code comes in handy:

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us");


The whole example is:

using System;

using System.Threading;

using System.Globalization;

 

namespace CurrencyFormat

{

  class Program

  {

    static void Main()

    {

      decimal value = 1234567.89M;

      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

      Console.WriteLine("{0:C}", value);

      Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");

      Console.WriteLine("{0:C}", value);     

      Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP");

      Console.WriteLine("{0:C}", value);

    }

  }

}


Output:

$1,234,567.89

1 234 567,89 €

Y1,234,568


List of all available culture names and identifiers is on MSDN.

kick it on DotNetKicks.com

Thursday, May 24, 2007

Syntax-Highlighted Code from Visual Studio as HTML

Maybe you wondered about syntax-highlighted code in this blog but blogger.com does not provide any tool for this. If you use Visual Studio, just try this CopySourceAsHtml add-in.

CopySourceAsHtml generates HTML source of your syntax-highlighted code in VS. You can select and copy your code as HTML to clipboard, so your syntax-highlighted code can be placed anywhere.

Here are my settings of CopySourceAsHtml add-in:


My "File Style" is:

border:1px solid black;

padding: 8pt;

width: 94%;

overflow: auto;

background-color: #F0F0F0;


Here is an example output:

using System;

 

class HelloWorld

{

  static void Main()

  {

    Console.WriteLine("Hello, World!");   

  }

}



kick it on DotNetKicks.com