Upcasting through covariant interfaces in a constrained generic C# method

Here's a subtle one. Assume you have the appropriate “using System.Collections.Generic;” clause included somewhere up above. Can you spot what's wrong with this code?

interface ITestInterface
{
}

class TestClass<T>
    where T : ITestInterface
{
    public void TestMethod()
    {
        IReadOnlyList<T> x = null;
        IReadOnlyList<ITestInterface> y = x;
    }
}

Seems reasonable, right? An IReadOnlyList is covariant in its stored type, so given that T is constrained to be an ITestInterface, assigning such a list of T to a list of ITestInterface should be fine. And yet, compiling this code will fail at “y = x”, being unable to implicitly convert the types.

After some hair-pulling, I eventually worked out that the solution is to add “class” to the constraints on T. It would seem that, otherwise, the compiler will assume that the generic type T will not have any kind of inheritance for which covariance will be relevant. So it doesn't consider that, and the cast fails.

Read this post

Adding the binary entropy function to LibreOffice Calc

Lately at work I've been doing some data analysis in LibreOffice Calc that requires the binary entropy function. The function itself looks like H2(x) =  − xlog2(x) − (1 − x)log2(1 − x), where 0log2(0) is taken to be 0. It's this latter point that makes things a little tricky. LibreOffice Calc doesn't have this function built-in, sadly, and you have to explicitly guard for the case where x is 0 or 1, which is not easy to pull off inside a cell.

So I wrote a basic macro that implements it:

Function BINENT(x)
    If x = 0 Or x = 1 Then
        BINENT = 0
    ElseIf x > 0 And x < 1 Then
        BINENT = -(x*Log(x) + (1 - x)*Log(1 - x))/Log(2)
    Else
        BINENT = Null
    End If
End Function

To be able to use BINENT in Calc, go to the “Tools” menu, “Macros”, “Organize Macros”, and select “LibreOffice Basic...”. You'll be shown a window with a library hierarchy on the left. Under the “My Macros” collection, select the “Standard” library, then click the “New” button on the right. This will open up the editor. Copy and paste the BINENT code above into the editor window [...]

Read this post


Page 1 of 1