I just spend ½ hour trying to find out, why my client callbacks where executing code inside the if (!Page.IsPostBack) region of my Page_Load method. It turns out, the Page class in .NET 2.0 has now got a new property called IsCallback. I then changed my if (!Page.IsPostBack) to if (!Page.IsPostBack && !Page.IsCallback). You learn something every day. The client callback feature of .NET 2.0 is really well implemented. If you haven't tried it yet, you should. It works like a charm and the things you can do with it, is absolutely incredible. Thumbs up to the architects of that feature. The father of ASP.NET Scott Guthrie is probably one of them.

If you used to be a VB developer, but for some reason are writing C# now, you probably miss a couple of functions. I remember being a little frustrated when I did the conversion from VB.NET to C#. It was March 2005 and I made the shift on the .NET 2.0 beta platform. I couldn’t understand why C# didn’t have some of the simplest functions like IsNumeric() and IsDate(). Also Left(), Right() and Middle() were missing. You could add a reference to the Microsoft.VisualBasic namespace, but that seemed like overkill for a few simple methods.

So I decided to make my own static class in C# 2.0 called VBFunctions that would implement exactly the four methods I was missing so much. This seems pretty basic and it is. But I use these functions again and again and now I have a single place to find them. Here’s the class:

#region Using

using System;
using System.Globalization;
using System.Text.RegularExpressions;

#endregion

/// <summary>
/// A collection of commonly used functions
/// </summary>
public static class VBFunctions
{

/// <summary>
/// Checkes if a object is numeric or not. It wrappes the functionallity
/// of Double.TryParse method.
/// </summary>
public static bool IsNumeric(object expression)
{
if (expression == null)
return false;

double number;
return Double.TryParse(Convert.ToString(expression, CultureInfo.InvariantCulture), System.Globalization.NumberStyles.Any, NumberFormatInfo.InvariantInfo, out number);
}

/// <summary>
/// Checkes if an object is of type DateTime. It wrappes the functionallity
/// of DateTime.TryParse method.
/// </summary>
public static bool IsDate(object expression)
{
if (expression == null)
return false;

if (expression.GetType() == typeof(DateTime))
return true;

DateTime date;
return DateTime.TryParse(Convert.ToString(expression, CultureInfo.InvariantCulture), DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out date);
}

/// <summary>
/// Returns the the left n charecters from a string. It wrappes the
/// functionallity of the Substring() method.
/// </summary>
/// <param name="text">The original string value</param>
/// <param name="length">The length of the text to return from the left</param>
public static string Left(string text, int length)
{
if (text == null)
throw new ArgumentNullException("The text cannot be null");

if (length >= text.Length)
return text;

return text.Substring(0, length);
}

/// <summary>
/// Returns the the right n characters of a string. It wrappes the
/// functionallity of the Substring() method.
/// </summary>
/// <param name="text">The original string value</param>
/// <param name="length">The length of the text to return from the right</param>
public static string Right(string text, int length)
{
if (text == null)
throw new ArgumentNullException("The text cannot be null");

if (length >= text.Length)
return text;

return text.Substring(text.Length - length);
}

/// <summary>
/// Returns the string sequence between firstCharacter and secondCharacter in a string.
/// </summary>
/// <param name="text">The original string</param>
/// <param name="firstCharacter">The first charecter in the sequence</param>
/// <param name="secondCharacter">The second charecter in the sequence</param>
public static string Middle(string text, string firstCharacter, string secondCharacter)
{
if (text == null)
throw new ArgumentNullException(string.Format("The text cannot be null");

if (!text.Contains(firstCharacter) || !text.Contains(secondCharacter))
return string.Empty;

int start = text.IndexOf(firstCharacter) + 1;
int stop = text.IndexOf(secondCharacter) - 2;
return text.Substring(start, stop);
}

}