1

这个问题可能有点令人困惑,但很难在主题标题中明确这个问题。

我有这样声明和实现的方法:

public IList<string> GetBookTitles()
{
    IList<string> bookTitles = new List<string>();
    // do something to populate the bookTitles list.
    return bookTitles;
}

为什么我不能将此方法的结果传递给 a List<string>?毕竟List<string>是一种IList<string>

4

5 回答 5

2

好吧,对于初学者,只需查看 的成员IList并将其与List. List有一个IList没有的方法。(List有一个没有的BinarySearch方法IList,仅作为一个例子。)

例如,数组也实现IList了 。但是,数组不是 a List,因此您不能也不应该将 a 传递string[]给接受 a 的方法List<string>

你有几个可能的解决方案。一种方法是更改​​您的方法以返回 aList<string>而不是 a IList<string>(这就是我的建议)。如果那是您真正需要的,那么您不应该将返回类型限制为IList<string>. 另一个(较差的)选择是将结果转换回 a List<string>,然后再将其传递给下一个方法,因为您碰巧知道它是底层类型的真正含义。

于 2012-09-06T13:45:02.343 回答
1

毕竟List<string>是一种IList<string>

但也有其他种类的IList<String>

如果您的方法要返回一个IList<String>which is aReadOnlyCollection<String>怎么办?

IList<string> x = new ReadOnlyCollection<string>();
List<string> y = x;  //Huh?
于 2012-09-06T13:41:27.083 回答
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 不实现排序,因此您的应用程序会编译,但会在运行时崩溃。使用强制转换方法在尝试进行强制转换时会崩溃,但在这种情况下,您有责任确定这种强制转换是可行的,并且编译器不会试图猜测。

更好的方法是使用 as 而不是 cast 和 chek for null。IE:

List<string> myBooks = GetBookTitles() as List<string>;
if (myBooks != null)
    myBooks.Sort();
于 2012-09-06T14:19:08.330 回答
0

你应该可以,你只需要一个显式的转换。

List<string> foo = (List<string>)GetBookTitles()

应该这样做。

于 2012-09-06T13:44:53.400 回答
0

接口可以在不同的类中实现。因此,很难找到相应的类。

您可以从 IList 键入 cast 到 List !!!

于 2012-09-06T13:46:40.137 回答