3

一位同事有一个对象,上面有一堆通用列表集合。列表中的每种类型都实现了一个给定的接口。他希望能够创建一个包含所有其他列表的列表,这样他就可以循环并调用对象实现的方法。下面是一个简单的例子。

 List<Dx> dxs = new List<Dx>();
 dxs.Add(new Dx());
 dxs.Add(new Dx());

 List<Proc> procs = new List<Proc>();
 procs.Add(new Proc());

 List<List<IClean>> lists = new List<List<IClean>>();
 lists.Add(procs); // Error here
 lists.Add(dxs); // Error here

 foreach (List<IClean> list in lists)
 {
     foreach (IClean i in list)
     {        
         i.Clean();
     }
 }

Dx 和 Proc 都实现了 IClean。这是目标。这样的事情可能吗?或者,这是糟糕的编程吗?

.NET 4.0 版

4

4 回答 4

9

您可以只拥有一个List<IClean>包含IClean.

var list = new List<IClean>();
    list.Add(new Dx());
    list.Add(new Proc());

foreach(var clean in list)
{
   clean.Clean();
}

此外,如果您确实需要维护两个单独的实现列表,然后一起处理它们,您可以执行以下操作:

var dx = new List<Dx>();
var proc = new List<Proc>();

List<IClean> list = new List<IClean>();
list.AddRange(dx);
list.AddRange(proc);

foreach(var clean in list)
{
   clean.Clean();
}
于 2012-07-23T19:18:16.627 回答
4

您不能使用 aList或 an来执行此操作IList,因为这些类型不是协变的。换句话说,如果你有 a List<IClean>,你应该可以添加 a Dx,但如果你有 aList<Proc>你不应该。因此, aList<Proc>不是 a List<IClean>

但是,从 .NET 4 开始,您可以使用IEnumerable<>.

 List<Dx> dxs = new List<Dx>();
 dxs.Add(new Dx());
 dxs.Add(new Dx());

 List<Proc> procs = new List<Proc>();
 procs.Add(new Proc());

 List<IEnumerable<IClean>> lists = new List<IEnumerable<IClean>>();
 lists.Add(procs); 
 lists.Add(dxs); 

 foreach (List<IClean> list in lists)
 {
     foreach (IClean i in list)
     {        
         i.Clean();
     }
 }
于 2012-07-23T19:18:50.017 回答
3

怎么样:

using System.Linq;

...

foreach( var clean in procs.Cast<IClean>().Concat(dxs.Cast<IClean>()) )
{
    clean.Clean();
} 
于 2012-07-23T19:20:42.777 回答
0

这是将输出以下内容的 LinqPad 代码片段:

Proc 已清理 Dx 已清理 Dx 已清理

void Main()
{
    List<IClean> dxs = new List<IClean>();  
    dxs.Add(new Dx());  
    dxs.Add(new Dx());   

    List<IClean> procs = new List<IClean>();  
    procs.Add(new Proc());   

    List< List<IClean> > lists = new List< List<IClean> >();  

    lists.Add(procs); 
    lists.Add(dxs);

    foreach (List<IClean> list in lists)
    {      
        foreach (IClean i in list)      
        {                  
            i.Clean();      
        }  
    } 
}

// Define other methods and classes here
public interface IClean 
{
  void Clean();
}
public class Dx : IClean
{
    public  void Clean()
    {
        "Dx cleaned".Dump();
    }
}

public class Proc : IClean
{
    public void Clean()
    {
        "Proc cleaned".Dump();
    }
}
于 2012-07-23T19:26:19.080 回答