强制转换会导致不同的GetTypes

时间:2017-07-13 10:26:57

标签: c# casting

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

例如,如果要从ValueType Struct中进行显式转换,如Char into Byte,如下所示:

class Plant{}
class Flower:Plant{}

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

现在说我从自定义类花转换到它的基类工厂,为什么输出显示派生类而不管演员如何:

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

item.split(':')[1]

我想我的问题是,为什么类型不公开自定义类型的当前类型,即Plant,为什么它与开头的值类型不同?

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

2 个答案:

答案 0 :(得分:8)

第一次演员的结果是不同的值。它现在是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定义的XElement

答案 1 :(得分:2)

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

但是,还有 类型转化。那些可以是 inbuilt (如byte / char等基元的情况),或者它们可以作为自定义转换运算符提供(通过implicitexplicit运算符关键字)。在 的情况下,由代码决定会发生什么(可能是任何事情)。

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