[英]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.