此C++代码检查是否o为a Node *,如果是,则调用方法d.
if (Node * d = dynamic_cast<Node *>(o)) d->do_it();
在C#中编写等效的最短和/或最有效的方法是什么?
Jar*_*Par 21
假设那Node是一个class然后做以下
Node d = o as Node;
if (d != null) {
  d.do_it();
}
如果相反它是一个struct然后试试这个
if (o is Node) {
  ((Node)o).do_it();
}
从 C# 6(2015 年 7 月)开始,假设Node是 a class(或Nullable<T>、string等),使用您的示例
o是 a (实际上与转换为aNode不同——请参阅下面有关转换与转换的注释)o Nodedo_it()您可以使用空条件运算符:
(o as Node)?.do_it();
此语法还处理o实际上声明为Node,但碰巧是 的情况null。
如果您想保留强制转换变量,从 C# 7(2017 年 3 月)开始,您可以运行:
if (o is Node node)
{
    node.do_it();
}
node此时的变量在if语句之外的作用域内,相当于:
Node node = o as Node;
if (node != null) 
{
    node.do_it();
}
因此,如果您只想在 ois a时继续执行Node,您可以编写:
if (!(o is Node node)) 
{
    return; // or continue, etc
}
node.do_it();
// ...
注意:即使您直接指定类型然后询问该变量是否是该类型,is关键字也将始终返回falseif ois 。null
if (!(o is Node node)) 
{
    return; // or continue, etc
}
node.do_it();
// ...
和关键字is与asC++ 的作用相同dynamic_cast<T>:它们将检查指定的类型、子类型或接口,但实际上不会更改内存中的值。它们只是告诉编译器哪些方法应该在变量上可用。
C# 用户存在一个误用词,即我们交替使用“cast”和“convert”这两个词。这可能源于这样一个事实:我们通常知道基类型变量始终是子类型,因此当严格地我们应该使用强制转换语法时,我们使用转换语法:
string foo = null;
if (foo is string)
{
    // never gets here
    Console.WriteLine(foo);
}
value如果实际上不是 ,则此语法将在运行时抛出异常MySubType。
转换与转换的不同之处在于内存中的值可能会改变。考虑int和double。
void Foo(MyBaseType value)
{
    // let's assume `value` will always be a MySubType
    MySubType subTypeValue = (MySubType)value;
}
在每种情况下,存储在内存中的文字值都会改变格式。  ints 总是可以用 a 来表示double——数据永远不会丢失——因此有一个定义implicit operator可以将内存中的数据处理成新的格式。  doubles 是浮点值并且范围大于ints,不能保证不会丢失数据,因此 C# 需要通过 进行显式转换(通常称为“显式转换”),以explicit operator向编译器表明我们可以丢失数据。
通过类,我们可以定义自己的隐式和显式运算符,它们将以我们认为合适的方式操作数据。这就是转换和转换之间的误用变得混乱的地方。
void Foo()
{
    // implicit converting
    int x = 1;
    double y = x;
    // explicit converting
    y = 1.5;
    x = (int)y;
}