C#'s equivalent to VB.NET's DirectCast

csauve picture csauve · Apr 21, 2010 · Viewed 46k times · Source

Does C# have an equivalent to VB.NET's DirectCast?

I am aware that it has () casts and the 'as' keyword, but those line up to CType and TryCast.

To be clear, these keywords do the following;

CType/() casts: If it is already the correct type, cast it, otherwise look for a type converter and invoke it. If no type converter is found, throw an InvalidCastException.

TryCast/"as" keyword: If it is the correct type, cast it, otherwise return null.

DirectCast: If it is the correct type, cast it, otherwise throw an InvalidCastException.

After I have spelled out the above, some people have still responded that () is equivalent, so I will expand further upon why this is not true.

DirectCast only allows for either narrowing or widening conversions on the inheritance tree. It does not support conversions across different branches like () does, i.e.:

C# - this compiles and runs:

//This code uses a type converter to go across an inheritance tree
double d = 10;
int i = (int)d;

VB.NET - this does NOT COMPILE

'Direct cast can only go up or down a branch, never across to a different one.
Dim d As Double = 10
Dim i As Integer = DirectCast(d, Integer)

The equivalent in VB.NET to my C# code is CType:

'This compiles and runs
Dim d As Double = 10
Dim i As Integer = CType(d, Integer)

Answer

Greg Bogumil picture Greg Bogumil · Apr 21, 2010

It seems clear that the functionality you want is not in C#. Try this though...

static T DirectCast<T>(object o, Type type) where T : class
{
    if (!(type.IsInstanceOfType(o)))
    {
        throw new ArgumentException();
    }
    T value = o as T;
    if (value == null && o != null)
    {
        throw new InvalidCastException();
    }
    return value;
}

Or, even though it is different from the VB, call it like:

static T DirectCast<T>(object o) where T : class
{
    T value = o as T;
    if (value == null && o != null)
    {
        throw new InvalidCastException();
    }
    return value;
}