Sunday 8 December 2013

Nothing is not null

I have to switch between writing legacy vb.net and c# on a daily basis and generally don't find this to be much of a problem, but a came across an interesting difference when trying to find the equivalent of c#'s default keyword. The default keyword returns the default value for a type T: default(T), zero for numeric types, null for nullables etc. It turns out that Nothing can be used in vb.net in this way. I always assumed null and Nothing where equivalent between vb.net and c#; I was wrong.

null == 0 // False
Nothing = 0 ' True

false == null // False
False = Nothing ' True
Taken from the official documentation: Nothing represents the default value of any data type. For reference types, the default value is the null reference. For value types, the default value depends on whether the value type is nullable.

There doesn't appear to be an equivalent of pure null in vb.net, you would have to check if it was a reference or value type explicitly. I don't like the implicitness of Nothing, but it fits with vb.net's general implicit conversions (which I also don't like).

False = 0 ' True
"1" = 1 ' True
' etc. etc.

Monday 24 June 2013

Anonymous function in anger with Memoize

About a year ago I blogged about anonymous functions, lambdas and delegates. I've had cause to use these principals in anger to create a memoize function; not exactly original but interesting never the less. I made this memoize function, which takes an anonynous function that takes 2 parameters.

static Func<T1, T2, TResult> Memoize<T1, T2, TResult>(Func<T1, T2, TResult> f)
{
    var dict = new Dictionary<Tuple<T1, T2>, TResult>();
    return (a, b) =>
    {
        TResult result;
        if (!dict.TryGetValue(Tuple.Create(a, b), out result))
        {
            result = f(a, b);
            dict.Add(Tuple.Create(a, b), result);
        }
        return result;
    };
}

N.B. It uses the .net4 Tuple class to store the 2 parameters, for the sake a simplicity I haven't generalized this for 1 or > 2 parameters, or made it an extension method. You then need to wrap the function you want memoizing.

var myFunc1 = Memoize((Func<int, int, MyClass1>)Some.Dot.Namespace.Func1);
var myNewClass = new MySomethingClass();
var myFunc2 = Memoize((Func<string, string, MyClass2>)myNewClass.Func2);

while(true)
{
    var result = myFunc1(1,2);
    var result2 = myFunc2("1","2");
}

The results of the memoized functions are cached inside the function calls, leading to better performance if the function is a called with the same parameters many times in the loop.

Saturday 27 April 2013

The curious case of null coalescing arithmetic

or how the simple things trip you up

I was writing a quick bit of code to add two nullable integers. To cope with the null, I used the wonderfully simple null coalescing operator ?? in C# to convert the integers to zero, like this:
int result = a ?? 0 + b ?? 0;
The result was wrong as demonstrated below:
int? a = 2;
int? b = 4;

int c = a ?? 0 + b ?? 0;
// Result:
// c = 2;
The obvious answer was a problem with operator precedence and a few brackets later fixed the problem:
int c = (a ?? 0) + (b ?? 0);
// Result:
// c = 6;
But why was it doing in the first instance? A little playing with linqpad later and it turns out the + operator has a much higher precedence than ??, so it was actually doing:
int c = a ?? ((0 + b) ?? 0);
This reads as: a, or if a is null then 0 + b, if 0 + b is null then zero. The mistake I made was because I'm so used to using ?? as a simple substitution of the preceding variable I wasn't thinking of it as a 'real' operator with precedence and ordering.

Thursday 31 January 2013

Asp.net will actually let you handle errors like this

VB.Net on a ASP.Net completely legit web page will do this:
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        On Error GoTo OwDear
Stupid:
        On Error Resume Next
        Throw New Exception("Dun gone wrong.")
        On Error GoTo OwDear
        Throw New Exception("Another error.")
OwDear:
        MsgBox("Another error.")

    End Sub
Documented: http://msdn.microsoft.com/en-us/library/5hsw66as.aspx This is just awful!