簡體   English   中英

方法C#的通用抽象參數

[英]Generic abstract argument for method C#

我有這個代碼示例。 我不知道它為什么不編譯。 它不允許從D轉換為A<B>

D繼承A<C> C繼承B ,這意味着我應該能夠將D傳遞給A<B>方法參數吧? 我可能在這里遺漏了一些明顯的東西。

using System.Collections.Generic;

public class Program
{
    public void Main()
    {
        var d = new D();
        Foo(d);  //Cannot convert D to A<B>

    }

    private void Foo(A<B> bar)
    {

    }   
}

public abstract class A<TypeB> where TypeB : B
{
     public abstract List<TypeB> list { get; set; } 
}

public abstract class B
{
}

public class C : B
{

}

public class D : A<C>
{
     public override List<C> list { get; set; }
}

這個問題已在本網站上被問過數百次。

假設你有一碗水果。 是一碗蘋果嗎? 蘋果是一種水果,為什么一碗水果不是一碗蘋果? 很明顯因為一碗水果已經含有香蕉,所以不是一碗蘋果。

假設你有一碗蘋果。 這是一碗水果嗎? 你想說“蘋果是一種水果,因此一碗蘋果就是一碗水果”。 但這是錯誤的。 一碗水果是你可以放入香蕉的東西 ,因為有一個操作,你可以在一碗水果上執行,你不能在一碗蘋果上執行,一碗蘋果不能用於碗的情況下水果預計。

您想要的轉換類型的技術名稱是“通用協變轉換”。 C#僅在少數特定情況下支持通用協變轉換:

  • “外部”類型必須是接口或委托,例如, IEnumerable<T>
  • “inner”類型必須是引用類型,如字符串,而不是值類型,如int。
  • 必須將“外部”類型標記為協方差安全; 這由編譯器檢查。

您可以在期望IEnumerable<Fruit>的上下文中使用IEnumerable<Apple> ,因為無法將香蕉放入IEnumerable<Fruit> 但是你不能將你的A<Apple>類用作A<Fruit>因為編譯器不相信你已經阻止了另一種類型Banana的可能性,它擴展了Fruit只用於接受Apple的方法。

在這個網站上搜索“協方差和逆變”,你會發現很多關於此的問題。

暫無
暫無

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

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