C#类型转换,如何避免错误?

时间:2012-07-23 19:09:12

标签: c# asp.net

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

 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 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分:4)

您无法使用ListIList执行此操作,因为这些类型不是协变的。换句话说,如果您有List<IClean>,则应该可以向其添加Dx,但如果您有List<Proc>,则不应该。List<Proc>。因此,List<IClean>不是IEnumerable<>

从.NET 4开始,您可以使用 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(); } } 执行此操作:

{{1}}

答案 2 :(得分:3)

怎么样:

using System.Linq;

...

foreach( var clean in procs.Cast<IClean>().Concat(dxs.Cast<IClean>()) )
{
    clean.Clean();
} 

答案 3 :(得分: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();
    }
}