2017-10-20 271 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)也是一種值類型。