2010-09-15 39 views
7

什麼是「從任何類型S到任何接口類型T,只要S不密封並且提供了S不執行T。」其實是指?什麼是「從任何類型S到任何接口類型T,只要S不密封,並且提供S不實現T.」其實是指?

我碰到這在C#語言規範here傳來:

6.2.4顯式引用轉換

顯式引用轉換 是:

  • ...
  • 從任何類型S到任何接口類型T,pro vided S也不 密封,並提供S不 實現T.

我能明白「只要S不密封」的意思,但我不知道如果我明白「只要S不不執行T「的意思。

例如:

class S {}//not sealed, nor does it implement T 
interface T {} 
... 
T t = (T)new S();//will throw InvalidCastException. 

難道是因爲它是在規格僅枚舉表達一個明確的引用轉換,所有的語法正確的方式不管它是否會拋出異常或不?或者它是否意味着我不知道的其他一些東西(截至目前爲止)?

在此先感謝。

+0

注意:在您的示例中存在顯式轉換。否則它不會編譯。所有的編譯時都很好。轉換在運行時爆發的事實是* explicit *轉換的典型特徵。有時他們會拋出,有時會成功。相反,如果'S'實現了'T',則會有一個***隱式***參考轉換(參見其他小節)。所以他們說'S'沒有實現'T'的原因是否則就會有另一個(優越的)轉換可用。 – 2015-04-24 22:03:12

回答

6

的雙關語中的「不封」部分:

class S {} //not sealed, nor does it implement T 
interface T {} 

class S2 : S, T { } 

    S s = new S2(); // S reference to an S2 instance, implicit conversion 
    T t = (T)s;  // OK, s refers to an S2 instance that does implement T 

難道是因爲它是在規格僅枚舉表達一個明確的參考轉換的所有語法正確的方式,...

是的,編譯器必須允許它,除非它知道轉換是不可能的。

如果你看看T t = (T)s;,如果S被封了,那麼編譯器肯定知道轉換是不可能的。但是對於非密封的S,它將不得不消除s引用S2類型的可能性,這是不實際的/可能的(S2可能在另一個程序集中)。

+0

_大聲笑,沒有密封的部分確實告訴繼承**是**涉及。沒有立即看到;)。明確閱讀的好教訓! – 2010-09-15 07:31:50

+0

謝謝!懷疑我可以自己做到。 – blizpasta 2010-09-15 07:36:49

0

您確定這不是文字錯誤嗎?

前提是S 實現T.

編輯:我找到了參考:http://msdn.microsoft.com/en-us/library/aa691291(v=VS.71).aspx

也就是說明確引用轉換,則意味着不隱! 因此,句子「從任何類型到任何接口類型T,假如S不是密封的,並且S沒有實現T」是正確的,它不能是隱式轉換,所以它必須是顯式的(並且不是保證它會成功)。

+0

我認爲這可能是一個錯誤。但是,考慮到「這很可能是你的代碼中的錯誤,而不是編譯器中的錯誤」的類比,我可能只是不知道如何正確解釋它。 – blizpasta 2010-09-15 07:29:08

-1

看起來這全是關於用戶定義的轉換。

你絕對不能施放S級到接口裝置T,如果S沒有實現T.

+0

用戶定義的轉換在這裏不重要。僅僅因爲你提到了一個充當S的對象,並不意味着它完全是S而不是S的超集。這個超集可以用標準轉換規則轉換爲T. – 2010-09-15 07:52:01

0

的規範去說:

顯式引用轉換是引用類型之間的轉換,這種轉換需要運行時檢查以確保它們是正確的。

換句話說,這裏列出的轉換類型是那些顯式轉換,即由於這兩種類型之間缺乏顯式關係,因此編譯器無法在編譯時檢查此類轉換是否可能並且有效。此類轉換嘗試將在程序執行期間解決,並可能導致例外,如果轉換不可行的話。

運行時顯式轉換的規範示例可能會失敗,但也可能成功,將從接口類型S轉換爲接口類型T,其中S和T不相關。成功取決於底層對象是否實現了這兩個接口。

你問到的問題 - 從類型S到接口類型T,其中S沒有實現T(並且不是密封的)時的特殊好奇的例子是當S是COM對象時,T是COM類型庫中未明確列出的COM接口由coclass實現。在這種情況下,轉換可能會失敗,但它也可能成功,具體取決於coclass的特定IUnknown :: QueryInterface實現。 (注意,在技術上,這種情況下的coclass正在實現這個接口,但並沒有將它發佈給編譯器)

當然,@Henk Holterman S2:S,T的例子也是一個很好的例子,可以成功。

相關問題