Skip to content

Home

IStaySharp.WebBrowser 0.9.0.1

I updated the IStaySharp.WebBrowser control with some bug fixes.

  • DocumentText fix in IEBrowser
  • Fix of member TranslateAccelerator in IDocHostUIHandler
  • ScrollBarsEnabled fix in IEBrowserSiteBase

More information can be found on IStaySharp.

Parse versus TryParse in .NET 2.0

In .NET 2.0 you will notice that every data has among others an extra method called TryParse. TryParse and Parse are semantically the same but differ in the way they handle errors. Parse method will throw an exception if it cannot convert the string, whereas the TryParse method returns a boolean to denote whether the conversion has been successfull or not, and returns the converted value through an out parameter.

int result = 0; 
bool success = true;

string badValue = "12a45"; 
string goodValue = "1245";

try { 
  result = int.Parse(badValue); 
} 
catch { 
  success = false; 
}

Debug.Assert(success == false); 
Debug.Assert(result == 0);

success = true;

try { 
  result = int.Parse(goodValue); 
} 
catch { 
  success = false; 
}

Debug.Assert(success == true); 
Debug.Assert(result == 1245);

// int.TryParse

success = int.TryParse(badValue, out result);

Debug.Assert(success == false); 
Debug.Assert(result == 0);

success = int.TryParse(goodValue, out result);

Debug.Assert(success == true); 
Debug.Assert(result == 1245);

The reason why the TryMethod is introduced, is because exceptions are expensive. On http://www.codinghorror.com/blog/archives/000358.html you find a benchmark tool and you notice that the (default) Parse method is a lot slower.

One tip: For extensive use of string concatenation you use the StringBuilder class, for converting data types you apply the TryParse method.

Nullable types in .NET 2.0

In .NET 1.1 you cannot assign the NULL value to a value type (e.g. int, float, etc.). There are some situations where this is needed, typically in database scenarios. In .NET 2.0 there is a new type called nullable. The nullable type implements the INullableValue interface and looks like:

public interface INullableValue 
{ 
  bool HasValue { get; } 
  object Value { get; } 
} 

The idea is that a nullable type combines a value (Value) of the underlying type with a boolean (HasValue) null indicator. The underlying type of a nullable type must be a value type.

Nullable<int> x = 9;

Debug.Assert(x.HasValue); 
Debug.Assert(x == 9); 
Debug.Assert(x.Value == 9); 
Debug.Assert(x.GetValueOrDefault(5) == 9);

x = null; 

Debug.Assert(x.HasValue == false); 
Debug.Assert(x.GetValueOrDefault(5) == 5);

You can also use the ? type modifier to denote a nullable type.

int? y = 9; 

Debug.Assert(y.HasValue); 
Debug.Assert(typeof(int?) == typeof(Nullable<int>)); 

In .NET 2.0 there is a new operator, called the null coalescing operator, ??. For example the statement x ?? y is x if x is not null, otherwise the result is y. Note that this operator also works with reference types.

int? a = null; 
int? b = 6; 

Debug.Assert((a ?? b) == b); 

a = 9; 

Debug.Assert((a ?? b) == a); 

b = null; 

Debug.Assert((a ?? b) == a);

RemotingHelper in .NET 2.0 (using generics)

RemotingHelper is a little helper class by Ingo Rammer that enables you to use interfaces to access remote objects instead of the implementation. In .NET 2.0 there are a lot of new features, and one of them are generics. Especially with the RemotingHelper we deal with types and with the GetObject method we can use generics to parameterize the method by type.

In .NET 1.1 we need to write something like

ICustomerService customerService = RemotingHelper.GetObject(typeof(ICustomerService)) as ICustomerService;

when using generics in .NET 2.0 we can simply write

ICustomerService customerService = RemotingHelper.GetObject<ICustomerService>();

No need to cast and no typeof operator! Below you find a version of the RemotingHelper using generics

using System; 
using System.Collections.Generic; 
using System.Runtime.Remoting;

public class RemotingHelper { 

  private static bool isInit; 
  private static IDictionary<Type, WellKnownClientTypeEntry> wellKnownTypes;

  public static T GetObject<T>() 
  { 
    if (!isInit) 
      InitTypeCache();

    WellKnownClientTypeEntry entry = wellKnownTypes\[typeof(T)\];

    if (entry == null) 
    { 
      throw new RemotingException("Type not found!"); 
    }

    return (T)Activator.GetObject(entry.ObjectType, entry.ObjectUrl); 
  }

  public static void InitTypeCache() 
  { 
    isInit = true; 
    wellKnownTypes = new Dictionary<Type, WellKnownClientTypeEntry>();

    foreach (WellKnownClientTypeEntry entry in RemotingConfiguration.GetRegisteredWellKnownClientTypes()) 
    { 
      if (entry.ObjectType == null) 
      { 
        throw new RemotingException("A configured type could not be found. Please check spelling"); 
      }

      wellKnownTypes.Add(entry.ObjectType, entry); 
    } 
  } 
} 

CruiseControl.NET and Visual SourceSafe

One way of setting up CC.NET and VSS is that CC.NET is responsible for getting the latest version (setting the attribute autoGetSource to true of the sourcecontrol node in the ccnet.config file) or NAnt by using the vssget task of NAntContrib for compiling the sources by NAnt. I always use the csc task instead of the solution task, therefore it is necessary to have a clean version of VSS, because VSS does not automatically delete files locally that have been deleted in the VSS database.

An alternative and better way is to set a shadow folder in VSS. A shadow folder contains a copy of the most recently checked-in version of each file in the project. This is exactly what we need for compiling the sources.

vssshadow

That way is CC.NET only using VSS for monitoring changes in the VSS database and/or labeling.