2017-10-20 125 views
-4

沮丧的我有两个类:混淆关于C#

public class Asset { } 

public class Stock : Asset 
{ 
    ... 
} 

当我写:

Stock m = new Stock(); 
Asset а = m;    
Stock s = (Stock) а; 

一切正常!

但是,当我这样写:

Asset а = new Asset();    
Stock s = (Stock) а; 

结果是InvalidCastException的,为什么呢?

+1

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/ – Bmo

+1

我不是C#大师,但它看起来像你在第二个错字例如:“Assetа= new Assert();”您的资产中有一个额外的“r”。 – bakoyaro

+0

为什么Asset最初是具体的?当然它应该是抽象的。 –

回答

1

A股资产。资产不是股票。

假设您的资产基类中有3种方法。这些也存在于股票中。因此,当您将股票投资到资产时,实际上是对股票进行限制。您的对象,即股票,被告知是资产。它知道该怎么做,因为它一个资产。

股票可能有3种不属于基础资产类别的方法。当您告诉资产是股票时,它不知道如何操作,因为存在不属于资产的部分股票。

1

在你的第一个实例,aAsset类型的引用,但它是一个对象的实际运行时类型是Stock

Stock m = new Stock(); 
Asset а = m;    
Stock s = (Stock) а; 

ma,并且s都到同一个实际的对象,其类型为Stock不同的引用。

这里,实际物体不是 a Stock。这只是一个Asset:从Asset

Asset а = new Assert();    
Stock s = (Stock) а; 

因为Stock继承,它是Asset一个超集。你可以假装StockAsset,这很好,因为Stock,部分是Asset - 加上它自己添加的任何东西。当然,这并不是两种方式:一个Asset没有所有的东西Stock了,所以你不能把它看作是一个Stock

你分配a在第一个例子中的对象并没有变成一个Asset,或创建一个新Asset并将其分配给m。它仍然是同一个对象。

参考的类型只是故事的一部分。

试试这个:

Stock m = new Stock(); 
Asset а = m;    

// This will print "Stock" -- it's still that same actual Stock object. 
Console.WriteLine(a.GetType()); 

Stock s = (Stock) а; 

类是 “引用类型”。它们存在于“堆”中,出现在某个地方的黑暗中,而且你只能操纵对它们的引用。整数和双打是不同的。他们是“价值类型”:

int n = 4; 
double d = (double)n; 

该代码实际上会创建一个新的double,等于4.0。 d不“引用”n;这是它自己的,不同的价值。这与参考类型的工作方式非常不同。

这东西是.NET类型系统的基本特征。 A struct(例如DateTime)也是一种值类型。