簡體   English   中英

C#類型轉換,如何避免錯誤?

[英]C# type conversion, how to avoid the error?

一個同事有一個對象,上面有一堆通用的列表集合。 列表中的每種類型都實現給定的接口。 他希望能夠創建一個包含所有其他列表的列表,以便他可以遍歷並調用對象實現的方法。 下面是一個簡單的例子。

 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

你可以只擁有一個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();
}

您無法使用ListIList執行此操作,因為這些類型不是協變的。 換句話說,如果你有一個List<IClean> ,你應該能夠為它添加一個Dx ,但如果你有一個List<Proc>你不應該。 因此, List<Proc>不是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();
     }
 }

怎么樣:

using System.Linq;

...

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

這是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();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM