此C ++代码检查o
是否为Node *
,如果是,则调用d
上的方法。
if (Node * d = dynamic_cast<Node *>(o)) d->do_it();
在C#中编写等效文件的最短和/或最有效的方法是什么?
答案 0 :(得分:20)
假设Node
是class
,请执行以下操作
Node d = o as Node;
if (d != null) {
d.do_it();
}
如果它是struct
,那么试试这个
if (o is Node) {
((Node)o).do_it();
}
答案 1 :(得分:1)
如果as
不是o
,则Node
运算符返回null:
Node d = o as Node;
if (d != null)
{
d.do_it();
}
答案 2 :(得分:1)
从C#6(2015年7月)开始,假设Node
是class
(或Nullable<T>
,string
等),请使用您的示例
o
是否为Node
(实际上与将o
转换为 Node
并不相同-请参阅有关投射vs在下面转换)do_it()
您可以使用null-conditional operator:
(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();
}
因此,如果您只想继续执行 o
是Node
,则可以编写:
if (!(o is Node node))
{
return; // or continue, etc
}
node.do_it();
// ...
注意:即使is
是false
,o
关键字也会始终返回null
,即使您直接指定类型然后询问如果该变量是该类型。
string foo = null;
if (foo is string)
{
// never gets here
Console.WriteLine(foo);
}
is
和as
关键字的作用与C ++的dynamic_cast<T>
相同:它们将检查指定的类型,子类型或接口,但实际上不会更改内存中的值。他们只是告诉编译器变量上应该使用哪些方法。
C#用户之间存在一个误称,我们可以互换使用“ cast”和“ convert”一词。这可能是由于我们经常知道一个基本类型变量总是一个子类型这一事实,因此我们在纯粹地使用时应使用 convert 语法。强制转换语法:
void Foo(MyBaseType value)
{
// let's assume `value` will always be a MySubType
MySubType subTypeValue = (MySubType)value;
}
如果value
实际上不是MySubType
,则此语法将在运行时抛出。
转换与强制转换的不同之处在于,内存中的值可能会发生变化。考虑int
和double
。
void Foo()
{
// implicit converting
int x = 1;
double y = x;
// explicit converting
y = 1.5;
x = (int)y;
}
在每种情况下,存储在内存中的文字值都会更改格式。 int
始终可以用double
表示-永远不会丢失数据,因此有一个已定义的implicit operator
可以将内存中的数据处理成新的格式。 double
s是浮点值且范围大于int
s,不能保证不会丢失数据,因此C#需要通过{{1进行显式转换(通常称为“显式强制转换”) }}向编译器表明我们可以丢失数据。
使用类,我们可以定义自己的隐式和显式运算符,它们将以我们认为合适的方式处理数据。这是 convert 和 cast 之间错误的称谓。
explicit operator
答案 3 :(得分:0)
您可以在C#中使用is
关键字。
if (o is Node)
{
}