Friday, June 22, 2007

avoid finalizers/use "using"

this is something we’ve gotten wrong a bit in places: in c#, only use a finalizer (i.e. a ~ClassName() method) if you need to clean-up unmanaged resources you’ve allocated. the reason for this is that if your class has a finalizer, the garbage collector will place it in the finalization queue and will not release it immediately. if you do have unmanaged resources and require a finalizer, implement IDisposable and do your cleanup in a shared Dispose(bool isDisposing) method. make sure to call GC.SuppressFinalize() in your Dispose() method so that if your client has already called Dispose(), your object is not placed in the finalization queue. for example:

public class ClassName : IDisposable
{

private bool m_IsDisposed;

~ClassName()
{

Dispose(false);

}

public void Dispose()
{

Dispose(true);

GC.SuppressFinalize(this);

}

public void Dispose(bool FromDisposeMethod)
{

if (!m_IsDisposed)
{

m_IsDisposed = true;

if (FromDisposeMethod)
{

//release managed resources; only do this if from Dispose method since they themselves might have been finalized

//...

}

//release unmanaged resources

//...

}

}

}

also, use "using" as much as possible. you can do this with any object that implements IDisposable:

using (MemoryStream ms = new MemoryStream())
{

//do whatever you want with ms

//...

}

using will automatically call Dispose() when the scope of this block ends, so you get very readable code and know that resources are properly released--

Monday, June 11, 2007

beware BIT columns in SQL2000

found a strange one today… if you have a BIT column and you write the following TSQL:

WHERE BitColumnName = 1

SQL Server doesn't quite do what you want it to do. rather than converting the 1 to a bit and then applying the where clause filter, it instead converts BitColumnName to an int and then applies the filter. this is problematic since you won’t be properly using indexes you have on the bit column. to avoid this, write:

WHERE BitColumnName = convert(bit, 1)

this is fixed in SQL2005--