此C ++代码检查 o 是否为 Node * ,如果是,则在 d 。
This C++ code checks if o is a Node * and if so, calls a method on d.
if (Node * d = dynamic_cast<Node *>(o)) d->do_it();用C#编写等效项的最短和/或最有效的方法是什么?
What's the shortest and/or most efficient way to write the equivalent in C#?
推荐答案从C#6(2015年7月)开始,假设 Node 是 class (或 Nullable< T> ,字符串等),使用您的示例
As of C# 6 (July 2015), assuming Node is a class (or Nullable<T>, string, etc), using your example where you
您可以使用空条件运算符:
(o as Node)?.do_it();此语法还处理 o 的情况实际上被声明为 Node ,但恰好是 null 。
This syntax also handles the case where o is, in fact, declared as Node, but happens to be null.
如果要保留强制转换变量,从C#7(2017年3月)开始,可以运行:
If you want to keep the cast variable, as of C# 7 (March 2017), you can run:
if (o is Node node) { node.do_it(); }变量 node 此时位于 if 语句之外的范围内,等效于:
The variable node at this point is in the scope outside of the if statement, equivalent to:
Node node = o as Node; if (node != null) { node.do_it(); }因此,如果您只想继续执行 if o 是一个 Node ,您可以编写:
So, if you want to only continue the execution if o is a Node, you can write:
if (!(o is Node node)) { return; // or continue, etc } node.do_it(); // ...注意:是如果 o 是关键字将总是 返回 false c> null ,即使您直接指定类型,然后询问该变量是否为该类型。
Note: The is keyword will always return false if o is null, even if you directly specify the type and then ask if that variable is that type.
string foo = null; if (foo is string) { // never gets here Console.WriteLine(foo); }铸造vs转换
是和,因为关键字的作用与C ++的 dynamic_cast< T> :它们将检查指定的类型,子类型或接口,但实际上不会更改内存中的值。他们只是告诉编译器变量上应该使用哪些方法。
Casting vs Converting
The is and as keywords do the same as C++'s dynamic_cast<T>: they will check against the specified type, subtype, or interface, but will not actually change the value in memory. They simply tell the compiler which methods should be available on the variable.
C#用户之间存在一个误称,我们可以互换使用 cast和 convert两个词。这可能是由于这样的事实,我们经常知道一个基本类型变量总是一个子类型,因此我们在纯粹地使用时应使用 convert 语法。强制转换语法:
There's a misnomer amongst C# users where we use the words "cast" and "convert" interchangeably. This likely stems from the fact that we often know that a base type variable is always going to be a subtype, and so we use the convert syntax when puritanically we should be using the cast syntax:
void Foo(MyBaseType value) { // let's assume `value` will always be a MySubType MySubType subTypeValue = (MySubType)value; }如果 value,此语法将在运行时抛出不是 MySubType 。
转换与强制转换的区别在于记忆可能发生变化。考虑 int 和 double 。
Converting differs from casting in that the value in memory may change. Consider int and double.
void Foo() { // implicit converting int x = 1; double y = x; // explicit converting y = 1.5; x = (int)y; }在每种情况下,存储在内存中的文字值都会更改格式。 int 始终可以用 double 表示-永远不会丢失数据-因此是已定义的隐式运算符,它将把内存中的数据处理为新格式。 double 是浮点值,并且范围大于 int s,不能保证不会丢失数据,因此C#需要通过 explicit运算符进行显式转换(通常称为显式强制转换),以向编译器指示我们可以丢失数据。
In each of these cases, the literal value stored in memory changes format. ints can always be represented by a double--there will never be a loss in data--and so there is a defined implicit operator that will manipulate the data in memory into the new format. doubles, being floating point values and having a range larger than ints, cannot guarantee no loss in data, so C# requires an explicit conversion (usually termed "explicit cast") via the explicit operator to indicate to the compiler that we're okay with losing data.
使用类,我们可以定义我们自己的隐式和显式运算符,它们将以我们认为合适的方式处理数据。这是 convert 和 cast 之间的误称。
With classes, we can define our own implicit and explicit operators which will manipulate the data whatever way we see fit. This is where the misnomer between convert and cast gets messy.
using System; public class Program { public static void Main() { Foo foo = new Foo(); Bar bar = (Bar)foo; // writes "1" (or would, if the program compiled) Console.WriteLine(bar); // throws compilation error: "Cannot convert type `Foo' to `Bar' via built-in conversion" bar = foo as Bar; // note: the same would happen if `foo` was type int? and `bar` was type `double?` // even though double? can be converted to int? } } class Foo { public readonly int Value = 1; public static explicit operator Bar(Foo foo) { return new Bar(foo.Value.ToString()); } } class Bar { public readonly string Value; public Bar(string value) { Value = value; } }更多推荐
与C ++的dynamic
发布评论