Wednesday, May 25, 2011

Optional Parameters

.NET 4.0 added the often requested ability to specify a default value for a parameter making it optional for callers. The optional parameters have to be at the end of the parameter values and must be constants.
Generally they should be used where you would have created an overloaded method just to pass in a default value for one or two parameters. Don’t use them in place of good object initialization code or for every parameter a function takes.
For example the following overloaded methods:
/// <summary>
/// Return the contents of the text node associated with the passed element.
/// Return the empty string if there is no text node.
/// </summary>
public static string GetText(XmlElement element) {
     return GetText(element, string.Empty);
}


/// <summary>
/// Return the contents of the text node associated with the passed element.
/// Return the default value if there is no text node.
/// </summary>
public static string GetText(XmlElement element, string defaultValue) {

Can be simplified into one method by making the second parameter optional:
/// <summary>
/// Return the contents of the text node associated with the passed element.
/// Return the default value if there is no text node 
/// or empty string if not specified.
/// </summary>
public static string GetText(XmlElement element, string defaultValue = "") {

Note while you can use constants like int.MinValue and long.MaxValue, string.Empty is a field on the String class and cannot be specified. You have to use "" for empty strings.

Tuesday, May 24, 2011

IEnumerable(T) != IEnumerable

String.Join(String, IEnumerable(of T)) was added in .NET 4.0 as a new overloaded method that takes a strongly-typed enumeration and returns a separated string. This is great and something we had previously done in a wrapper function. However, one thing to be careful here is that passing in an ArrayList will not throw an exception (compile or runtime) but may not give you the results you are expecting.
For example the following code:
ArrayList array = new ArrayList() {1, 2, 3};
string joinedString = String.Join(",", array);
Console.Write(joinedString);

Will write out:
System.Collections.ArrayList

Not:
1, 2, 3

Thursday, July 15, 2010

Old dogs can learn new tricks

About a year ago I wrote about using generics and creating thread-safe access to the Web Cache in ASP.NET. In that example I used a pattern that I had copied from some example code and used the classes Type itself to lock the block of code.

lock (typeof(CacheUtils)) {...}

I've since learned this is a bad idea (not a Really Bad Idea but bad enough). After reading articles like Don't Lock Type Objects and Safe Thread Synchronization I've realized the errors of my ways. The better pattern is to use an internal lightweight objects. For example:

private static readonly object locker = new object();
lock (locker) {...}

Tuesday, April 13, 2010

JS editing in VS 2008

When you have JavaScript in an .aspx file Visual Studio 2008 will list all of the functions in a drop down at the top of a page. However once you move the JS to a separate file VS suddenly loses this ability. You can trick it into regaining this feature with the following steps.

In the .js file add the following to the top and bottom of the file:
//<html xmlns="http://www.w3.org/1999/xhtml"><head><title></title><script type="text/javascript">
…
//</script></head><body></body></html>

And then in Tools -> Options -> File Extentions map js to the HTML editor:

Tuesday, April 28, 2009

Generic enum parsing

Saving an enum value to a string (say for XML persistence) and reading it back in you are forced to write code like the following:
Colors colorValue = (Colors) Enum.Parse(typeof(Colors), colorString);

Now this has always bothered me. I don't know whether it's the return Cast or passing in the object type but the whole syntax seems clunky. So given my new found love of generics I thought there had to be a better way. So I created the following method:

public static T ParseEnum<T>(string value) {
return (T)Enum.Parse(typeof(T), value, true);
}

Now I can write the following:

Colors colorValue = ParseUtils.ParseEnum<Colors>(colorString);
Seems a lot cleaner.