Reputation: 4040
I have aprogram
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;
}
}
}
On executing above I am getting:
Cannot implicitly convert type
'System.Collections.Generic.IList<string>'
to
'System.Collections.Generic.List<string>'
. An explicit conversion exists (are you missing a cast?).
Since, List derives IList , this should't fail. Then why C# is throwing this error?
Upvotes: 0
Views: 358
Reputation: 1206
While you can guarantee that all List
objects are of type IList
, you can't guarantee that all IList
objects are of type List
, since it could be an entirely different class that is implementing the interface. This means that in the line
List<string> dd= Program.get();
you are trying to tell the compiler that the IList
is actually a List
, but it doesn't know that. The IList
could actually be derived from a different subclass not even related to List
. You could do an explicit cast,
List<string> dd= (List<string>)Program.get();
but this could lead to runtime issues if it were ever possible for Program.get()
to return something other than List
which happened to implement IList
.
It is much better to explicitly state the return type of get()
as List<string>
if you really need access to features only available in List
, or to just declare the type of dd
as IList<string>
if the IList
interface provides all of the methods you ever intend to call.
As an example, consider the following:
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();
}
}
}
We can see that both Bar
and Baz
are of type Foo
, but we are never guaranteed which type gets returned from getMyFoo()
, only that it is of type Foo
. We could try explicitly casting myFoo
to one or the other, but we would generally fail at runtime because Baz
is not of type Bar
or vice versa.
Upvotes: 7