【问题标题】:C#, Generic Lists and InheritanceC#、泛型列表和继承
【发布时间】:2011-03-16 00:07:42
【问题描述】:

我有一个名为 Foo 的类,它定义了 A 类型的对象列表:

class Foo {
    List<A> Items = new List<A>();
}

我有一个名为 Bar 的类,它可以保存和加载 B 类型对象的列表:

class Bar {
    void Save(List<B> ComplexItems);
    List<B> Load();
}

B 是 A 的子类。Foo、Bar、A 和 B 在库中,用户可以创建任何类的子类。

我想做的事情如下:

Foo MyFoo = new Foo();
Bar MyBar = new Bar();

MyFoo.Items = MyBar.Load();
MyBar.Save(MyFoo.Items);

显然这行不通。有没有避免创建中间列表的巧妙方法?

谢谢,安迪

【问题讨论】:

  • “B 是 A 的孩子”是什么意思?在您给出的代码清单中,A 和 B 是类型参数。
  • “孩子”是什么意思?你的意思是“派生类”吗?
  • 好的,但在您的示例中,A 和 B 是 Foo 和 Bar 类型定义中使用的类型参数。这很令人困惑。
  • 好的。考虑 A = 形状和 B = 圆形。我想将一个圆圈列表加载到一个形状列表中,并保存一个我知道都是圆圈的形状列表。 Circle 派生自 Shape。

标签: c# list generics inheritance


【解决方案1】:

使用 .NET 4.0 和 IEnumerable&lt;T&gt; 代替 List&lt;T&gt; (http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx),否则在 T(列表项类型)上也使 Save 通用。

【讨论】:

  • 我看到 IEnumerable 是我需要的,但遗憾的是我不能使用 .NET 4.0。呸!
  • 然后我将 Bar 类设为通用:class Bar&lt;T&gt; where T : A { void Save(List&lt;T&gt; ComplexItems); List&lt;T&gt; Load(); } 并用 Bar 实例化它。或者只让方法本身通用(可能更容易,尤其是类型推断):void Save&lt;T&gt;(List&lt;T&gt; ComplexItems) where T : A; List&lt;T&gt; Load&lt;T&gt;(); where T : A }
【解决方案2】:

如果您可以将保存功能更改为采用 IEnumerable,那么您可以:

void Save(IEnumerable<B> ComplexItems);
Save(MyFoo.Items.Cast<B>());

【讨论】:

  • 谢谢。加载函数呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-01
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多