2012-03-06 45 views
0

我有以下代碼,我學習。我知道我不能將「父母」隱式轉換爲「孩子」(但我可以反過來)。但是,我試圖明確轉換,但無法使其工作。我假設孩子轉換爲父母時應該丟失數據。如何顯式投射類型(自定義類)

class Parent 
{ 
    int A=5; 
} 

class Child:Parent 
{ 
    int B=5; 
    int C=2; 
} 

Parent parent = new Parent(); 
Child ch = new Child(); 

ch=ch as Parent //or (Parent)ch; 
+0

'我假設孩子在轉換爲父母時應該會丟失數據。「#不。您對c#中某些重要概念的工作方式似乎有一些非常糟糕的想法。我建議Jon Skeet的書「深入研究C#」以及閱讀msdn文檔,並可能討論書面規範。 http://msdn.microsoft.com/en-us/library/ms173149(v=vs.80).aspx – asawyer 2012-03-06 12:50:39

+0

@asawyer謝謝但是如何從double轉換爲int - 存在數據丟失 – user970696 2012-03-06 12:53:22

+1

這正是我的意思是。 'double'到'int'沒有繼承鏈。你在這裏處理蘋果和橘子,並混合術語。 – asawyer 2012-03-06 12:54:39

回答

3

ch一個Parent,沒有必要做投

如果你測試這個表達式

bool isParent = ch is Parent 

你會看到isParent = true。您可以在任何地方使用ch作爲Parent而不使用任何投射

4

您爲什麼需要這樣做?由於繼承關係,A ChildParent。無論你需要一個Parent你可以通過一個Child它應該工作(如果它不是你違反Liskov Substitution Principle)。

你可以看一下在Child,如果它是一個Parent像這樣:

Child ch = new Child(); 
Parent childAsParent = ch as Parent; 

而且是相當無意義...

使用as Parent(Parent)之間的區別是你是否」會發生錯誤或沒有。如果ch不是Parent的一個實例,那麼在這種情況下它總是會是「安全」的(如果使用as),那麼只會給您留空。如果演員不能完成,另一個會投擲InvalidCastException

0

問題是chChild,而您正在嘗試將Parent指定給它。您是否嘗試過通過

Parent parent = new Parent(); 
Child ch = new Child(); 
parent=ch as Parent //or (Parent)ch; 

Parent pa = ch as Parent; 
0

變化

Parent parent = new Parentk(); 
Child ch = new Child(); 
ch=ch as Parent //or (Parent)ch; 

替換最後一行你施放一個孩子家長,但結果是一個子對象

0

修改您的最後一行

Parent castRef = ch as Parent; 
Parent castRef = (Parent)ch; 

前者是一個「安全演員」,它將檢查ch實際上是否爲Parent類型(或者是其後繼者),如果是,則返回對Parent類的引用,否則返回null。這與as運算符(如if(ch是Parent)...一樣)

後者是一個明確的轉換,並且不會檢查,可能會使您引用某個不是或來自父母的後代),當你使用它時會出現奇怪的錯誤。

我總是比較喜歡以前的版本。

並以解釋方式回答您的查詢;你需要一個新的父類型變量引用來分配轉換。

2

鑄造,當你需要你的類型設置爲正確的類型......

Child ch = child as Parent; //Wrong 
Child ch = (Parent)child; //Wrong 
Parent p = child as Parent; //Correct 
Parent p = (Parent)child; //Correct 
var p = child as Parent; //Correct (var will end up being a Parent) 
var p = (Parent)child;  //Correct (var will end up being a Parent) 

不同類型的演員可以解釋here(StackOverflow的問題)。


我認爲當轉換爲父母的孩子應該會丟失數據。

這是一個不正確的假設。您不是「失去」數據,但您正在更改類型,這會更改您可以訪問的成員。將其更改回Child,並且成員BC仍保留其值。

0

請注意對象實例和引用之間的差異。

new Child(); 

實例化(創建)類Child的實例。這意味着現在有一個對象(在「堆」中),但是您沒有直接訪問該對象的權限,您可以通過對它的引用進行間接訪問。一旦對象被實例化,你就不能改變它的類型。

Child ch; 

限定了一個具有子接口的引用,在默認情況下指的是沒有對象(IE:空)

Parent parent; 

限定了一個具有父接口的引用。

一旦這些引用不存在,然後你可以將它們分配給使用直線對象,如:

parent = new Parent(); 

ch = new Child(); 

因爲孩子從父母繼承(如其他人所說,它「是一個「父」),父引用也可以引用「子對象」。 IE:

parent = new Child(); 

parent = ch; 

但你將只能夠訪問由父通過父參考限定的子對象的所述部分。請注意,這不需要演員陣容。但是,您需要向另一個方向投射。也就是說,如果它仍然是一個孩子的對象,但你只有一個家長參考,到目前爲止,你需要一個投得到一個孩子參考:

ch = (Child)parent; 

ch = parent as Child; 

前者將拋出如果演員不能執行,則爲例外。如果演員不能執行,後者會將null賦值給ch。