簡體   English   中英

如何正確返回接口列表類型?

[英]How do I properly return a List of Interfaces type?

使用以下代碼,我在“返回書籍”上收到“無法隱式轉換”編譯錯誤。 線。

我認為,因為我返回一個實現IPublication的書籍對象列表,這應該工作正常嗎?

public interface IPublication {}

public class Book : IPublication {}

public List<IPublication> GetBooks()
{
    List<Book> books = new List<Book>();
    return books;
}

我注意到,如果我將一本書作為單個IPublication對象返回,它可以正常工作。 引入List<>需要顯式轉換。

作為我正在使用的解決方法:

return books.Cast<IPublication>().ToList();

問題是List<IPublication>可以容納任何繼承自IPublication類。 由於編譯器不知道您不會嘗試將Magazine放入GetBooks()的結果中,您必須編寫如下函數:

public List<IPublication> GetBooks() 
{ 
    List<IPublication> books = new List<IPublication>(); 
    // put only books in here
    return books; 
} 

如果你的函數返回一個不需要通過索引訪問的不可變列表(並且你在C#4上),你可以這樣寫:

public IEnumerable<IPublication> GetBooks()         
{         
    List<Book> books = new List<Book>();         
    return books;         
}

如果你可以返回一個IEnumerable<T>但你正在使用C#3,你可以做cdhowie建議的事情:

public IEnumerable<IPublication> GetBooks()         
{         
    List<Book> books = new List<Book>();         
    return books.Cast<IPublication>();         
}

如果您使用的是C#2,最好只使用我提出的第一種方法。

這不是一個安全的轉換。 想象一下,如果有人把雜志放在你的書籍清單中。

public class Library
{
    public List<Book> books = new List<Book>();
    public List<IPublication> GetBooks()
    {
      return books;
    }
}

別處,

Magazine mag = ...;
List<IPublication> pubs = someLibrary.GetBooks()
pubs.Add(mag);

在.NET 4中,你可以返回IEnumerable<IPublication>如所描述這里 ,沒有創建任何新的對象。 cdhowie還為較低版本提供了良好的解決方案。 只需刪除.ToList() ,然后返回一個IEnumerable

我意識到你的具體案例是安全的。 但編譯器無法驗證。

除非您使用的是.NET 4,否則必須使用解決方法。

考慮是否有人這樣做:

public class Magazine : IPublication { }

// Somewhere...

var foo = something.GetBooks();
foo.Add(new Magazine());

如果運行時允許從List<Book>List<IPublication> ,那么您將被允許將雜志添加到書籍列表中! 這打破了類型系統,因為如果某些東西仍然引用了List<Book> ,它肯定不會期望Magazine在其中,它會把Magazine看作是一本書,然后運行時崩潰(或更糟糕的是 - 數據損壞或不安全的事情)隨之而來。

我認為你正在使用舊版本而不是c#4.0,我們有協方差和逆變 所以你只能按元素轉換list元素。

暫無
暫無

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

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