tags:

views:

359

answers:

2

I've read somewhere on MSDN that the equivalent to C#'s "is" keyword would be dynamic_cast, but that's not really equivalent: It doesn't work with value types or with generic parameters. For example in C# I can write:

void MyGenericFunction<T>()
{
    object x = ...
    if (x is T)
        ...;
}

If I try the "equivalent" C++/CLI:

generic<class T>
void MyGenericFunction()
{
    object x = ...
    if (dynamic_cast<T>(x))
       ...;
}

I get a compiler error "error C2682: cannot use 'dynamic_cast' to convert from 'System::Object ^' to 'T'".

The only thing I can think of is to use reflection:

if (T::typeid->IsAssignableFrom(obj->GetType()))

Is there a simpler way to do this?

+1  A: 

You can use safe_cast where you would use dynamic_cast in native C++ and trap the System::InvalidCastException. In terms of compatible types the semantics of asking if you can convert types could pick up a broader range of types than checking identity. You may actually want the added flexibility of IsAssignableFrom.

I don't think there's an efficient equivalent to the good old dynamic_cast idiom we're used to, certainly nothing as compact.

Andy Dent
A: 

It's on MSDN:

How to: Implement is and as C# Keywords in C++

In a nutshell, you need to write a helper function like so:

template < class T, class U > 
Boolean isinst(U u) {
   return dynamic_cast< T >(u) != nullptr;
}

and call it like this:

Object ^ o = "f";
if ( isinst< String ^ >(o) )
    Console::WriteLine("o is a string");
Guido Domenici
Maybe you misunderstood my question. I know that MSDN article. I mentioned it in my question. And I explained why it doesn't work for me. dynamic_cast isn't equivalent to C# "as". It only works for reference types.
Niki
Oops, should read questions more carefully. It does work for generic types, but not for value types.
Guido Domenici