与C ++的dynamic_cast等效的C#是什么? [英] What's the C# equivalent to C++'s dynamic_cast?

查看:120
本文介绍了与C ++的dynamic_cast等效的C#是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此C ++代码检查 o 是否为 Node * ,如果是,则在<$ c上调用方法$ c> 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


  1. 检查 o 是否为 Node (实际上与将 o 转换为 Node 的效果不同-请参阅有关强制转换的注释与下面的转换相比)

  2. 如果这样,请调用 do_it()

  3. 立即丢弃演员表值

  1. check if o is a Node (not actually the same as converting o to a Node--see note about casting vs converting below)
  2. if so, call do_it()
  3. immediately discard the cast value

您可以使用空条件运算符

(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 是<$ c $,则code>关键字将总是 返回 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_cast等效的C#是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆