2014-11-25 28 views
2

所以,我遇到了以下「問題」,我真的很好奇它背後的原因。明確的投射算子vs與T

考慮以下幾點:

public class B 
{ 

} 

public class A<T> 
{ 
    private void AFunc(T t) 
    { 
     FuncRequireB((B)t); // Not allowed 
     FuncRequireB(t as B); // Allowed 
    } 

    private void FuncRequireB(B b) 
    { 

    } 
} 

我知道優雅的解決方案是在類定義T作爲B,但我想知道爲什麼「(B)t」和「T爲B」在這種情況下不同。我知道「as」是安全的,所以如果轉換無法完成,它可以生成爲null,另一方面,如果轉換不成功,顯式強制拋出異常,但爲什麼編譯器應該關心這個呢?在這種情況下,我看不到他們之間的區別。

預先感謝您!

+0

[C#泛型簡介](http://msdn.microsoft.com/en-us/library/ms379564%28v=vs.80%29.aspx) – MethodMan 2014-11-25 14:17:10

+5

用'T'做的一切都比較好,但是再次,我來自英國。 – 2014-11-25 14:22:17

回答

5

區別在於通常是如果編譯器知道一個轉換,則轉換可以執行用戶定義的轉換。對於泛型類型,編譯器沒有這些信息。如果你想只執行一條直線引用轉換轉換,你可以轉換爲object第一:

FuncRequireB((B)(object) t); 

可用的轉換這方面從來沒有非常我清楚,說實話 - 但它確實工作。

請注意,如果您可以約束TB類型兼容,則會更乾淨。如果它的位只適用於特定的類型參數,那麼你的類型不是非常通用的。

+0

我認爲,雖然你是正確的,但它是相當差的做法,並表明一個糟糕的設計。 – 2014-11-25 14:18:59

+0

@JamesRalston:因此是最後一段。 – 2014-11-25 14:21:40

+0

嗯,我只是想強調一下。對於靜態類型語言爲您提供的安全性來說,雙重鑄造是一種非常令人震驚的規避行爲,我真的很想強調這一點。 「as」的運作方式與明確演員不同。它在不成功的拳擊上返回'null'(並且null引用異常是一個完全不同的主題),但是這個投射非常危險。 – 2014-11-25 14:58:42