我有一个程序
using System;
using System.Collections.Generic;
namespace Generic
{
public class Program
{
public static void Main()
{
List<string> dd= Program.get();
}
public static IList<string> get()
{
List<string> str = new List<string>();
return str;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在执行上面我得到:
无法隐式转换
'System.Collections.Generic.IList<string>'为
'System.Collections.Generic.List<string>'.存在显式转换(您是否错过了演员?).
既然,List派生IList,这不应该失败.那么为什么C#会抛出这个错误呢?
虽然您可以保证所有List对象都是类型IList,但您无法保证所有IList对象都是类型List,因为它可能是实现接口的完全不同的类.这意味着在线
List<string> dd= Program.get();
Run Code Online (Sandbox Code Playgroud)
你试图告诉编译器它IList实际上是一个List,但它不知道.该IList实际上可以从不同的子类,甚至是不相关的衍生List.你可以做一个明确的演员,
List<string> dd= (List<string>)Program.get();
Run Code Online (Sandbox Code Playgroud)
但如果有可能Program.get()返回实际发生的其他内容List,这可能会导致运行时问题IList.
最好显式地声明返回类型,get()就List<string>好像你真的需要访问仅可用的功能一样List,或者只是声明类型,dd就IList<string>好像IList接口提供了你打算调用的所有方法一样.
例如,请考虑以下事项:
interface Foo {
public void doSomething();
}
class Bar : Foo {
public override void doSomething() {
Console.WriteLine("Hello World!");
}
}
class Baz : Foo {
public override void doSomething() {
Console.WriteLine("Goodbye World!");
}
}
class Program {
public static void Main(string[] args) {
Foo myFoo = getMyFoo();
myFoo.doSomething();
}
static Random random = new Random();
static Foo getMyFoo() {
if (random.NextDouble() < 0.5){
return new Bar();
}
else {
return new Baz();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以看到,无论Bar和Baz有型的Foo,但我们永远不会保证其类型会从返回getMyFoo(),只知道它是类型Foo.我们可以尝试显式地转换myFoo为一个或另一个,但我们通常会在运行时失败,因为Baz它不是类型Bar,反之亦然.