C++/CLI-问题:是否有与C#"is"关键字相同的或者我是否必须使用反射?

Nik*_*iki 13 c++-cli

我在MSDN上的某个地方读过,相当于C#的"is"关键字将是dynamic_cast,但这并不是真正等效的:它不适用于值类型或泛型参数.例如在C#中我可以写:

void MyGenericFunction<T>()
{
    object x = ...
    if (x is T)
        ...;
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试"等效"C++/CLI:

generic<class T>
void MyGenericFunction()
{
    object x = ...
    if (dynamic_cast<T>(x))
       ...;
}
Run Code Online (Sandbox Code Playgroud)

我得到一个编译器错误"错误C2682:不能使用'dynamic_cast'从'System :: Object ^'转换为'T'".

我唯一能想到的就是使用反射:

if (T::typeid->IsAssignableFrom(obj->GetType()))
Run Code Online (Sandbox Code Playgroud)

有更简单的方法吗?

Gui*_*ici 15

它在MSDN上:

如何:在C++中实现和C#关键字一样

简而言之,您需要编写一个这样的辅助函数:

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

并称之为:

Object ^ o = "f";
if ( isinst< String ^ >(o) )
    Console::WriteLine("o is a string");
Run Code Online (Sandbox Code Playgroud)

  • C#的`as`也不适用于值类型:`dynamic_cast`与`as`完全相同.使用`safe_cast`来转换为值类型.语义等同于C#的语义:将错误转换的异常抛给值类型,对于错误转换返回"null"引用类型. (10认同)
  • 也许您误解了我的问题。我知道该MSDN文章。我在问题中提到了它。我解释了为什么它对我不起作用。dynamic_cast不等同于C#“ as”。它仅适用于引用类型。 (3认同)

And*_*ent 6

您可以使用在本机C++中使用的safe_cast位置dynamic_cast并捕获System :: InvalidCastException.在兼容类型方面,询问是否可以转换类型的语义可以选择比检查标识更广泛的类型.实际上,您可能希望增加IsAssignableFrom的灵活性.

我不认为有效地相当于dynamic_cast我们习惯的古老成语,当然没有任何紧凑的习惯.