簡體   English   中英

有關通用函數參數的問題

[英]Question about generic function parameter

我只是想知道為什么將System.Collections.Generic.List<string>傳遞給此函數test(ICollection<object> t)將不起作用,為什么我不能像將string傳遞給test2(object t)

對我來說沒有多大意義!

因為ICollection不是僅輸出接口,所以它不是協變的。

考慮以下代碼:

void test(ICollection<object> t)
{
    t.Add(new TextBox());
}

List<string> lst;
test(lst);

test試圖將TextBox塞入List<string>時應該發生什么?

ICollection<object>的約定是可以放入任何object ,並且輸出的項目始終為object類型。 但是List<string>僅滿足該合同的一半。

因為在C#3.0和.NET 3.5或更低版本中, List<T>實現ICollection<T> 這意味着List和ICollection的通用類型必須相同。 在這種情況下,盡管字符串是從對象派生的,但不能將List<sting>分配給List<object> 不能以相同的方式將List<string>分配給ICollection<object>

在C#4.0和.NET 4.0中,我們具有協方差和逆方差的概念,可讓您將List<string>分配給IEnumerable<object>

這是一段可在C#4.0中運行的代碼

public static void Test(IEnumerable<object> input) {
    // do something
}

static void Main(string[] args) {
    var input = new List<string>();
    Test(input);
}

方法test()期望參數值具有實現接口ICollection<object> 確保類List可以。

@Ben的解釋很棒,是的,@ Gallahad建議,.Net 4.0中實現了有用的協變和逆變接口。 這些使您能夠執行與您嘗試執行的操作類似的操作,並確保Ben的示例中的陷阱代碼無法與它們一起編寫。

同時,您當然可以做類似的事情

private static void PrintAll<T>(IEnumerable<T> list)
{
     foreach (var item in list)
     {
          Console.WriteLine(item.ToString());
     }
}

static void Main()
{
     List<int> numbers = Enumerable.Range(1, 10).ToList();
     PrintAll(numbers);
}

這是獲得協方差的好方法。 此外,您可以使用where子句將PrintAll的通用參數限制為方便的基類。

暫無
暫無

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

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