【问题标题】:Casting Causes Different GetTypes强制转换导致不同的 GetType
【发布时间】:2017-07-13 10:26:57
【问题描述】:

所以我对自定义类型如何在 .NET Framework 中存储数据没有深入的了解,但我正在寻找有关转换系统如何工作的解释。

例如,如果要将像 Char 这样的 ValueType 结构显式转换为 Byte,如下所示:

char C = '#';
byte B = (byte)C;
Console.WriteLine(B.GetType()); // Outputs "Byte"

我会被告知 B 是一个字节,这是完全有道理的。

现在假设我从自定义类 Flower 转换为其基类 Plant,为什么输出显示派生类而不管转换如下:

class Plant{}
class Flower:Plant{}

.

Flower Rose = new Flower();
Plant RoseBush = (Plant)Rose;
Console.WriteLine(RoseBush.GetType()); //Outputs Flower

Plant Rose = new Flower();
Plant RoseBush = (Plant)Rose;
Console.WriteLine(RoseBush.GetType()); //Outputs Flower as well

我想我的问题是,为什么类型不暴露自定义类型的当前类型,即 Plant,为什么这与一开始的 Value Types 不同?

另外,为什么花和植物的两个例子,虽然第一行写法不同,却输出相同的东西?

【问题讨论】:

    标签: c# casting


    【解决方案1】:

    第一次转换的结果是一个不同的值。现在是byte 而不是char

    第二个转换是引用转换。结果是相同的一组位 - 对同一对象的引用 - 只是具有不同的编译时类型。 GetType() 返回对象的实际执行时间类型,在两种情况下都是相同的(因为它是同一个对象)。

    您可以在示例中观察到这一点:

    // Variable names modified to follow normal conventions
    Flower rose = new Flower();
    Plant roseBush = (Plant) rose;
    Console.WriteLine(ReferenceEquals(rose, roseBush)); // True
    

    引用类型的强制转换可以产生不同的值,请注意,如果它们是自定义转换 - 但这些不是语言规范术语中的“引用转换”。例如:

    XElement element = new XElement("name", "value");
    string value = (string) element;
    

    这里value 确实不是对与element 相同对象的引用-它是对string 对象而不是XElement 对象的引用,通过显式转换为@ 定义的string 987654331@.

    【讨论】:

      【解决方案2】:

      C# 强制转换语法在不同的情况下会做不同的事情。当您谈论一个类和基类/子类/接口时,它是一个引用保留强制转换-您实际上所做的只是类型检查(即使只有这种情况其中编译器不知道它必须 工作 - 例如,在将子类型转换为基类型时省略)。在这种情况下,唯一改变的是编译器/JIT 正在考虑的类型。

      不过,也有类型转化。这些可以是内置(就像byte / char 等原语一样),或者它们可以作为自定义转换运算符提供(通过implicitexplicit 运算符关键字)。在那种的情况下,发生什么取决于代码(它可以是任何东西)。

      所以:这里的区别在于一个是内置的原始转换,一个是保留引用的类型检查。

      【讨论】:

        猜你喜欢
        • 2016-01-27
        • 1970-01-01
        • 2013-12-28
        • 1970-01-01
        • 1970-01-01
        • 2021-10-11
        • 2013-11-21
        相关资源
        最近更新 更多