繁体   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