[英]Any workarounds for structs failing to cast to object when the struct is the covariant type of a generic object being being casted in 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.