[英]Why can't I cast base reference to a variant interface implemented by derived class?
我有以下接口和類:
private interface ITest<in T1, out T2>
{
}
private class TestClass
{
}
private class TestClass<T1, T2> : TestClass, ITest<T1, T2>
{
}
有了這些,我可以做到:
TestClass testBase = new TestClass<Parent, Child> ();
TestClass<Parent, Child> testGeneric = (TestClass<Parent, Child>)testBase; // Works fine
ITest<Parent, Parent> testInterface = (ITest<Parent, Parent>)testGeneric; // Works fine
但如果我嘗試將兩者結合起來,我就做不到:
ITest<Parent, Parent> testInterface = (ITest<Parent, Parent>)testBase; // Fail!
為什么我不能直接投在這里? 這只是C#cast或variant接口的限制嗎?
如果接口的類型參數完全匹配泛型類的類型,它實際上是有效的:
ITest<Parent, Child> testInterfaceExact = (ITest<Parent, Child>)testBase; // Works
問題是TestClass
真的不是ITest<T1, T2>
。 它與界面無關,因此您不能只寫:
(ITest<T1, T2>)new TestClass();
另一方面,非通用TestClass
與通用TestClass
相關。 因此,以下指令實際上是一個向下轉發:
(TestClass<T1, T2>)new TestClass(); // will fail at run time...
Downcast可能在運行時成功或失敗,具體取決於實際對象是否為派生類型。 編譯將始終成功。
現在,如果您想要對派生對象進行基本引用,那很好。 但是,如果您希望將其轉換為僅為派生類所知的任何內容(例如您的界面),則必須首先執行向下轉換:
TestClass derived = new TestClass<T1, T2>();
ITest<T1, T2> interf = (TestClass<T1, T2>)derived;
您甚至不必轉換為接口,因為泛型類已經實現了該接口。
變量類型參數的問題越來越嚴重。 如果編譯器無法訪問泛型參數的方差信息,則無法檢查是否可以進行強制轉換。 一旦轉換為泛型類,編譯器將能夠正確推斷方差並分配引用:
TestClass derived = new TestClass<Parent, Child>();
ITest<Parent, Parent> interf = (TestClass<Parent, Child>)derived;
你的最后一行工作的事實,那就是:
ITest<Parent, Child> testInterfaceExact = (ITest<Parent, Child>)testBase;
只是因為您沒有更改泛型類型,因此編譯器不必在此行推斷方差信息(它沒有)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.