内存表示的向下转型 [英] Memory Representation of a downcasting

查看:51
本文介绍了内存表示的向下转型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

让我们从经典开始:

基类:带名字的资产

子类:拥有所有权的股票
子类:带抵押贷款的房子



我到处都读到了向下倾斜的爆炸,但不知怎的,我想知道记忆中到底发生了什么。我先在这里输入一段代码:



Hello guys,
Lets start with the classical:
Base class: Asset with Name
Subclass: Stock with Ownership
Subclass: House with Mortgage

I have read everywhere the explination of downcasting but somehow I would like to understand what exactly is happening in memory. I will type here the piece of code first:

<pre lang="c#">
            House h = new House();
            Asset asset2 = h;
            //Case B The downcast fails.
            Stock stock2 = (Stock)asset2;  





如果B我得到一个无效的强制转换异常:无法将Intro.House类型的对象强制转换为Intro.Stock。简单的探索将是资产2不是股票,是房子,这就是为什么它失败。



在aaset2 = h我们说我们现在有一个类型的对象资产但含量为h。探索是在内存中具有变量a(对象实例资产的引用1)和h(对象实例House的引用2),我们复制引用2,这意味着变量a将包含将指向对象h的引用2。基本上它意味着我们在类型a中包含了h的内容。据我所知,内存中的类表示是对象包含对象metada(对象类型,threding标志和GC标志)和字段值的引用和对象。

第一个问题是,如果我们现在指向一个类型为House的对象,为什么a.Owner抛出异常?这个限制在哪里保存在内存中。

第二个问题与最后一行代码有关,其中asset2根据编译器属于House类型,不能转换为类型Stock。在我的locals变量窗口中,它在asset2上显示的类型为Intro.Asset {Intro.House}。在这种情况下,资产2实际上是指向House的内容,而内容不是正确的类型,实际上并不是对象的类型?



For一个简单的例子,它是一个值类型而不是引用类型



object obj = 1;

int k;

k =(int)obj;



在这种情况下,向下转换是有效的,因为obj的内容是一个int。但是如何在运行时或作为工作来测试实例的类型?它是否包含在它所包含的字段中?并且由于资产包含一个Montgage,它不能被转换为拥有所有权的股票?



非常感谢,我希望我能解释一下很清楚。

推荐答案

你可以做什么取决于班级之间的关系:

如果你如此组织:

Exactly what you can do depends on the relationship between the classes:
If you have it organised like this:
public class Asset { }
public class Stock : Asset
    {
    public string Ownership { get; set; }
    }
public class House : Asset
    {
    public string Mortgage { get; set; }
    }

然后是的,你可以这样做:

Then yes, you can do this:

House h = new House();
Asset asset2 = h;



因为House来自Asset,所以House的任何实例也是资产的实例,就像福特也是一样汽车。

但你不能说:


Because a House derives from Asset, so any instance of a House is also an instance of an Asset, in the same way that a Ford is also a Car.
But you can't say:

House h = new House();
Asset asset2 = h;
Stock stock2 = (Stock)asset2;



因为房子不是股票 - 它们都来自资产,但它们包含不同的附加信息。

就像说福特是一辆汽车,而法拉利是一辆汽车,因此我的福特是法拉利



如果改变班级的推导,你可以这样做稍微:


Because a House is not a Stock - they both derive from Asset, but they contain different additional information.
It's like saying "a Ford is a Car, and a Ferrari is a Car, therefore my Ford is a Ferrari"

You can do it if you change the derivation of your classes slightly:

public class Asset { }
public class Stock : Asset
    {
    public string Ownership { get; set; }
    }
public class House : Stock
    {
    public string Mortgage { get; set; }
    }

现在这样可行:

Now this works:

House h = new House();
Asset asset2 = h;
Stock stock2 = (Stock)asset2;

因为房子既是股票又是资产。



基类的变量可以包含任何实例派生类(任何Car都是Car,无论是Ford还是Ferarri),系统会在运行时精确地确定它的类型 - 但是在编译时你只能使用适合变量类型的属性和方法,不是内容类型:

because a House is both a Stock and an Asset.

A variable of the base class can contain an instance of any derived class (any Car is a Car, whether it is a Ford or a Ferarri) and the system sorts out exactly which type it is at run time - but at compile time you can only use the properties and methods appropriate to the variable type, not the content type:

House h = new House();
Stock s = new Stock();
Asset a = h;
h.Mortgage = "Company";
h.Ownership = "Other Company";
s.Ownership = "Another Company";
s.Mortgage = "Company";           // ERROR
a.Mortgage = "Company";           // ERROR
a.Ownership = "Other Company";    // ERROR


如果您想要一个简单的答案,请:您在代码示例中演示的内容不是向上转换或向下转换。这是对等投射,原则上无效。因为,如果可以编译它,它将允许访问不存在的成员。我甚至要解释原因吗?应该很明显。



-SA
If you want a simple answer, please: what you demonstrate in your code sample is not up-casting or down-casting. This is peer-casting, which cannot be valid in principle. Because, if it was possible to compile it, it would give an access to non-existing member. Do I even have to explain why? Should be quite obvious.

—SA


Asset asset2 = h;

    Stock stock2 = (Stock)asset2;







asset2.Mortgage

将收到编译器错误,因为变量类型为Asset且无法访问House propreties。

will get a compiler error because the variable type is Asset and it has no access to House propreties.

Stock stock2 = (Stock)asset2

将得到运行时错误,因为实例类型是House类型。



Bassically asset2是Asset类型的变量,并且具有House类型的实例。



我想我只想弄清楚变量的类型和实例的类型是如何存储在内存中的。

will get a run time error because the instance type is of type House.

Bassically asset2 is a variable of type Asset and has an instance of type House.

I guess I am just trying to figure it out how the type of the variale and the type of the instance is stored in memory.


这篇关于内存表示的向下转型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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