如果方法返回接口类型,为什么不能将结果传递给具体类型?



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

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

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没有的方法。(仅举一个例子,ListBinarySearch方法,而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的强制转换!!!

相关内容

  • 没有找到相关文章

最新更新