这个问题可能有点令人困惑,但很难在主题标题中明确这个问题。
我声明并实现了这样的方法:
public IList<string> GetBookTitles()
{
IList<string> bookTitles = new List<string>();
// do something to populate the bookTitles list.
return bookTitles;
}
为什么我不能将此方法的结果传递给List<string>
?毕竟,List<string>
是一种IList<string>
。
答案 0 :(得分:2)
嗯,对于初学者,只需查看IList
的成员并将其与List
进行比较。 List
具有IList
没有的方法。 (List
有一个BinarySearch
方法IList
没有,只是作为一个例子。)
例如,数组也实现了IList
。但是,数组不是List
,因此您不能也不应该将string[]
传递给接受List<string>
的方法。
您有一些可能的解决方案。一种方法是改变你的方法以返回List<string>
而不是IList<string>
(这就是我的建议)。如果这是您真正需要的,那么您不应该将返回类型限制为IList<string>
。另一个(较差的)选项是在将结果传递给下一个方法之前将结果转换回List<string>
,因为你碰巧知道底层类型确实是什么。
答案 1 :(得分:1)
毕竟,
List<string>
是一种IList<string>
。
但还有其他种类的IList<String>
。
如果您的方法要返回IList<String>
而不是ReadOnlyCollection<String>
,该怎么办?
IList<string> x = new ReadOnlyCollection<string>();
List<string> y = x; //Huh?
答案 2 :(得分:1)
编译器在决定是否可以将GetBookTitles的结果赋值给变量时使用方法的签名而不是实现,因此它无法知道结果实际上是List。如果它允许你做这样的事情,那么你可以这样写:
List<string> myBooks = GetBookTitles();
myBooks.Sort();
在您的示例中,您可以执行此操作,事实上,如果您投射方法的结果,则可以执行此操作:
List<string> myBooks = (List<string>)GetBookTitles();
但是有一天你可以决定你的图书集是不可修改的,你可以按如下方式重写你的方法:
public IList<string> GetBookTitles()
{
IList<string> tmp = new List<string>();
// do something to populate the bookTitles list.
IList<string> bookTitles = new ReadOnlyCollection<string>(tmp);
return bookTitles;
}
ReadOnlyCollection没有实现Sort,所以你的应用程序会编译,但会在运行时崩溃。 使用强制转换方法会在尝试执行转换时崩溃,但在这种情况下,您负责决定这种转换是否可行并且没有编译器试图猜测。
更好的方法可能是使用as而不是cast和chek for null。即:
List<string> myBooks = GetBookTitles() as List<string>;
if (myBooks != null)
myBooks.Sort();
答案 3 :(得分:0)
你应该可以,你只需要一个明确的转换。
List<string> foo = (List<string>)GetBookTitles()
应该这样做。
答案 4 :(得分:0)
接口可以在不同的类中实现。因此,很难找到相应的班级。
您可以在IList中输入强制转换为List !!!