簡體   English   中英

為什么我不能將基類引用轉換為派生類實現的變量接口?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM