当前位置:  开发笔记 > 编程语言 > 正文

如果要求List <IFoo>,为什么我不能返回List <Foo>?

如何解决《如果要求List<IFoo>,为什么我不能返回List<Foo>?》经验,为你挑选了4个好方法。

我的理解是,如果S是一个子类的T,那么List不是一个孩子List.精细.但是接口有不同的范例:如果是Foo实现IFoo,那么为什么List不是(一个例子)List

因为可能没有实际的类IFoo,这是否意味着我在暴露a时总是必须强制转换列表中的每个元素List?或者这只是糟糕的设计,我必须定义自己的集合类ListOfIFoos才能与它们一起工作?对我来说似乎都不合理......

考虑到我正在尝试编程接口,那么暴露这样一个列表的最佳方式是什么?我目前正倾向于实际存储我的List内部作为List.



1> xtofl..:

List不是子类,List因为您无法MyOwnFoo在其中存储对象,这也恰好是一个IFoo实现.(利斯科夫替代原则)

存储List而不是专用的想法List是可以的.如果您需要将列表的内容强制转换为其实现类型,这可能意味着您的界面不合适.



2> Jon Skeet..:

这是一个为什么你不能这样做的例子:

// Suppose we could do this...
public List GetDisposables()
{
    return new List();
}

// Then we could do this
List disposables = GetDisposables();
disposables.Add(new Form());

此时,为了保存MemoryStreams而创建的列表现在有一个Form.坏!

基本上,这种限制是为了保持类型安全.在C#4和.NET 4.0中,对此的支持有限(称为方差),但由于上面给出的原因,它仍然不支持这种特定情况.



3> Tom Ritter..:

在返回的函数中,您必须使列表成为接口列表,并在创建对象时将其作为实现它的对象.像这样:

function List getList()
{
  List r = new List();
  for(int i=0;i<100;i++)
      r.Add(new Foo(i+15));

  return r;
}



4> David Kemp..:

大规模编辑 你将能够用C#4.0做到这一点,但 [感谢Jon]

你可以使用ConvertAll以下方法解决它:

public List IFoos()
{
    var x = new List(); //Foo implements IFoo
    /* .. */
    return x.ConvertAll(f => f); //thanks Marc
}

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有