2009-08-17 62 views
1

我正在使用派生類並使用as關鍵字將基類轉換爲它。當我這樣做時,派生類構造函數被調用,並且它的對象被初始化,但派生實例不會以初始化對象(具有空值)結束。這是一個代碼示例。使用「as」關鍵字丟失對象初始化

// classes 
public class Request 
{ 
    public Request(); 
    public Header Header{get;set;} 
} 

public class CreateRequest : Request 
{ 
    public Foo Foo{get;set;} 
    public Bar Bar{get;set;} 

    public CreateRequest():base() 
    { 
    this.Foo = new Foo(); 
    this.Bar = new Bar(); 
    } 
} 

public class SomeClass 
{ 
    private Response ProcessCreateRequest(Request request) 
    { 
    // request comes from a json request 
    CreateRequest createRequest = request as CreateRequest; 
    // values of Foo and Bar are null 
    [...] 
    } 
} 

是,「爲」通常用於derived->的基礎,而不是鹼基問題>派生或者是有工作別的東西嗎?

回答

7

直到jon雙向遊戲顯示正確回答這個問題,據我所知'as'關鍵字只是一種方法來執行強制轉換,如果強制轉換無效,則會抑制異常;它不應該自己調用任何構造函數

因此,您是否驗證過(例如,在調試器中)傳入的對象在投射之前是否已正確初始化?

+0

+1你說的沒錯,只有'只鑄造 - 沒有構造函數被調用。 – 2009-08-17 17:02:55

+0

我已經驗證的是構造函數被擊中。我實際上試圖解決的是一個請求沒有指定所有主體參數的情況。這殺了我,因爲我到了對象結構中,進來的null表示一個空對象,當訪問成員時它將開始拋出異常。我可以在演員陣容中捕捉到空洞,但似乎應該有一種更優雅地照顧它的方法。 – TahoeWolverine 2009-08-17 19:41:09

+0

您應該檢查JSON請求解串器是否正常工作。所以至少拋出一個不完整請求的異常。 – user7116 2009-08-17 20:17:02

3

作爲澄清的一點,as運算符不會調用有關對象上的任何方法。它只是發現對象是否可以轉換爲請求的類型,如果是,則返回實例作爲類型或如果不能(返回C#語言規範第7.9.11節「as操作符」)返回該實例。

從您顯示的代碼看來,CreateRequest沒有任何理由具有null屬性,除非JSON請求反序列化方法將其顯式設置爲null。你也可以說是這樣的話,通過調用:

var response = ProcessCreateRequest(new CreateRequest()); 
System.Diagnostics.Debug.Assert(response.Foo != null); 
System.Diagnostics.Debug.Assert(response.Bar != null); 

你會發現無論是as運營商和默認的構造函數工作正常。

+0

+1這也是正確的,因爲不會調用用戶定義的轉換。請參閱http://msdn.microsoft.com/en-us/library/cscsdfbt(VS.71).aspx – 2009-08-17 17:05:51

+0

是的7.9.11與以下內容拼寫:「請注意,某些轉換(例如用戶定義的轉換)不可行使用as運算符,而應該使用強制表達式來執行。「 – user7116 2009-08-17 17:09:21

1

問題是使用'as'不會調用構造函數。它只是將對象轉換爲新類型(在這種情況下,從Request到CreateRequest)。

就你的情況而言,由於Request沒有字段值......在投射後它們爲空。

+0

如果Request不是CreateRequest,那麼'as'-cast將返回null。默認構造函數創建具有非空值的屬性,因此在JSON反序列化中的某處,屬性被設爲null。 – user7116 2009-08-17 17:04:16

+1

我們正在談論C#...... JSON從哪裏來? – 2009-08-17 17:07:55

+1

他的代碼表示(或者說暗示)Request對象是由JSON請求反序列化產生的。 – user7116 2009-08-17 17:11:04

-1

此外,除了什麼斯蒂芬說,(使用「作爲」不能觸發構造函數),

...在年的問題,你的狀態

「我使用的是派生類將基類投射到它上面...「

您不能將基類轉換爲派生類,只能以相反方式,很清楚地(希望)您錯誤地陳述年代問題,或者您的假設無效某種程度上來說。你能更明確嗎?

+0

當且僅當派生類從相關基類派生時,纔可以將基類轉換爲派生類。 – user7116 2009-08-17 17:12:37

+0

@sixletter ...,你完全向後...你不能將一個基類的實例轉換爲派生類的類型。即。如果構建Animal的實例,則不能將該實例轉換爲輸入Pig。 otoh,如果你有一個豬的實例,你可以將它轉換成動物類型... – 2009-08-19 02:35:18

0

不能使用「as」關鍵字將基類的實例轉換爲派生類的實例。如果對象不是派生類的實例,那麼「as」關鍵字將不會將其轉換爲一個。

+0

那麼,在這種情況下,它是,有點。處理JSON請求時,請求中的參數與類的成員匹配。我的問題是,如果有人提出請求,說沒有身體,那麼請求對象中的對象開始在訪問其成員時拋出異常。 – TahoeWolverine 2009-08-17 19:46:05