簡體   English   中英

C# 協變轉換失敗

[英]C# Failing Covariant Cast

我正在嘗試創建具有一系列實現的通用表工廠之類的東西。 下面的示例是不言自明的,即使兩個類型屬性都標記為“out”,最終的轉換也不起作用。 我想,問題是 Table 不是一個接口,這會破壞演員陣容。 但它不應該是真正的接口,尤其是不是協變的。 任何想法如何正確地投射它? 絕對不想用反射來使用方法。

interface ITableRow { }

class Table<T> where T : ITableRow { }

interface ITableFactory<out TRow, out TTable>
    where TRow : ITableRow
    where TTable : Table<TRow>
{
    TTable CreateTable();
}

// example implementation:

class SuperRow : ITableRow { }

class SuperTableFactory : ITableFactory<SuperRow, Table<SuperRow>>
{
    public Table<SuperRow> CreateTable() { throw new NotImplementedException(); }
}

// run:

class VarianceTest
{
    public static void Test()
    {
        var factory = Activator.CreateInstance(Type.GetType("Snippets.Var.SuperTableFactory"));

        var casted = (ITableFactory<ITableRow, Table<ITableRow>>) factory; // cast fails
    }
}

您的SuperTableFactory聲稱會生成Table<SuperRow>的實例。 這意味着,無論您從中獲得什么表,您都可以添加SuperRows並讀取SuperRows

但是,您的ITableFactory<ITableRow, Table<ITableRow>>聲稱它生成Table<ITableRows> - 人們可以將ITableRows添加到並從中讀取ITableRows的表。

但是您的實際表工廠會生成Table<SuperRow> ——底層的行存儲是SuperRow 你不能讓別人把任何舊的ITableRow放在那里!

這就是你的演員失敗的原因。

如果您擺脫“人們可以向表中添加行”位,以及人們只能讀取行的 promise,您就可以解決這個問題。 那么Table的行存儲是否實際上是SuperRow並不重要,因為人們無法嘗試將其他類型的行放入其中。

您可以通過使Table<T>協變來做到這一點。 但是正如您所指出的,類不能是協變的,只能是接口。 所以你需要一個ITable<out T>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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