这个问题可能有点令人困惑,但很难在主题标题中明确这个问题。
我有这样声明和实现的方法:
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>
的一种。
首先,只需查看IList
的成员并将其与List
进行比较。List
具有IList
没有的方法。(仅举一个例子,List
有BinarySearch
方法,而IList
没有。)
阵列还实现了IList
,例如。但是,数组不是List
,因此不能也不应该将string[]
传递给接受List<string>
的方法。
你有几个可能的解决方案。一种方法是只更改方法以返回List<string>
,而不是IList<string>
(这就是我的建议)。如果这是您真正需要的,那么您不应该将返回类型限制为IList<string>
。另一个(较差的)选项是在将结果传递给下一个方法之前将其强制转换回List<string>
,因为您碰巧知道它是底层类型
毕竟,
List<string>
是IList<string>
的一种。
但也有其他种类的CCD_ 21。
如果您的方法是返回一个IList<String>
,而不是ReadOnlyCollection<String>
,该怎么办?
IList<string> x = new ReadOnlyCollection<string>();
List<string> y = x; //Huh?
编译器在决定是否可以将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,而不是强制转换和检查null。即:
List<string> myBooks = GetBookTitles() as List<string>;
if (myBooks != null)
myBooks.Sort();
你应该能够,你只需要一个显式的转换。
List<string> foo = (List<string>)GetBookTitles()
应该这样做。
接口可以在不同的类中实现,但这些类并不相同。因此,很难找到相应的类。
您可以键入从IList到List的强制转换!!!