首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# .NET将InterfaceImplementingClass对象的集合传递给接受接口对象集合的例程

C# .NET将InterfaceImplementingClass对象的集合传递给接受接口对象集合的例程
EN

Stack Overflow用户
提问于 2009-02-25 00:40:31
回答 4查看 1.8K关注 0票数 5

我有例行公事

代码语言:javascript
复制
public void SomeRoutine(List<IFormattable> list) { ... }

然后我试着把这个例程叫做

代码语言:javascript
复制
List<Guid>list = new List<Guid>();
list.Add(Guid.NewGuid());
SomeRoutine(list);

如果编译时出错,它就会失败。System.Guid实现了IFormattable,但我得到的错误是

无法从“System.Collections.Generic.List”转换为“System.Collections.Generic.List”

注意:如果您只使用Guid数组,您将得到相同的错误。仿制药不是原因..。

但!鉴于此

代码语言:javascript
复制
public void SomeRoutine2(IFormattable obj) { ... }

还有这个

代码语言:javascript
复制
Guid a = Guid.NewGuid();
SomeRoutine2(a);

它会编译!所以问题是为什么?为什么我能够将Guid对象(实现IFormattable)传递给接受IFormattable对象的例程,但是当我试图将它扩展到集合(泛型列表、数组或其他任何东西)时,我会得到一个转换错误。

我花了很长时间才找到答案,我觉得这是最好的去处。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-02-25 00:46:11

这就是每个人都在谈论的全部协变问题。它将在.NET 4.0中工作。

见此处:http://blogs.msdn.com/charlie/archive/2008/10/28/linq-farm-covariance-and-contravariance-in-visual-studio-2010.aspx

再读一读:

http://www.infoq.com/news/2008/08/GenericVariance;jsessionid=188695B18864997E8D360E0EEED5983E

http://blogs.msdn.com/lucian/archive/2008/10/02/co-and-contra-variance-how-do-i-convert-a-list-of-apple-into-a-list-of-fruit.aspx

票数 8
EN

Stack Overflow用户

发布于 2009-02-25 04:39:00

这是一个典型的泛型用例;请尝试:

代码语言:javascript
复制
public static void SomeRoutine<T>(IList<T> list) where T : IFormattable
{ ... }

现在,在SomeRoutine内部,您可以访问所有IFormattable成员,但它将使用:

代码语言:javascript
复制
List<Guid>list; ...
SomeRoutine(list); // note no need to specify T

编辑:另外,我还介绍了这个场景中4.0协方差和泛型之间的差异。

票数 5
EN

Stack Overflow用户

发布于 2009-02-25 01:26:32

问题是,List不仅是一个可以读取某些IFormattables的集合,也是一个可以添加IFormattables的集合。清单符合第一个要求,但不符合第二个要求。如果SomeRoutine是

代码语言:javascript
复制
public void SomeRoutine(List<IFormattable> list)
{
    list.Add(5);
}

Int32是一个IFormattable,所以该方法应该能够将它添加到它所要求的列表中。如果编译器允许您传递列表,这是行不通的。

C#所引用的新的BFree 4.0特性将允许您告诉编译器什么时候这些事情是安全的。你可以说

  • 虽然我要求提供一个IFormattable引用,但我只会阅读它。如果它真的是一个Guid引用,那么我可以安全地将它作为一个IFormattable来处理,并且我不会尝试为它分配一个Int32。
  • 虽然我要求提供一个IFormattable引用,但我只会写信给它。如果它确实是一个对象引用,那么我可以安全地将我的IFormattable分配给它,如果当前的值不是IFormattable,也不重要,因为我不会读取它。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/584319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档