I keep seeing this error, over and over again:
Cannot convert from
Item<Foo>
toItem<IFoo>
.
This is clearly nonsense; an object of type Item<Foo>
is statically guaranteed to be able to do absolutely everything that an Item<IFoo>
can do (and possibly more), so why is the compiler refusing to accept my perfectly valid code?
I have a method that accepts an Item<IFoo>
as an argument. For some reason, it refuses to accept an Item<Foo>
as input, even though Foo
implements IFoo
. This makes no sense at all. I can pass a Foo
in place of an IFoo
, but I can't pass an Item<Foo>
in place of an Item<IFoo>
. Why?
public class Item<T>
{
public readonly int ID;
public readonly T Data;
...
}
public void ProcessItem(Item<IFoo> item)
{
Console.WriteLine(item.ID);
}
ProcessItem(new Item<Foo>());
Classes in C# are invariant, so depending on your requirements you'll have to create an interface and implment that:
public interface IItem<out T> { ... }
public class Item<T> : IItem<T> { ... }
IItem<IFoo> item = new Item<Foo>();
Note that it is not necessarily safe to assign a Class<Subtype>
to a Class<Basetype>
. A common example is List<T>
:
List<object> l = new List<string>(); //won't compile
l.Add(3);
C# only allows variance annotations on interfaces and delegates, and only when it is safe to do so.
I keep seeing this error, over and over again:
Cannot convert from
Item<Foo>
toItem<IFoo>
.
This is clearly nonsense; an object of type Item<Foo>
is statically guaranteed to be able to do absolutely everything that an Item<IFoo>
can do (and possibly more), so why is the compiler refusing to accept my perfectly valid code?
I have a method that accepts an Item<IFoo>
as an argument. For some reason, it refuses to accept an Item<Foo>
as input, even though Foo
implements IFoo
. This makes no sense at all. I can pass a Foo
in place of an IFoo
, but I can't pass an Item<Foo>
in place of an Item<IFoo>
. Why?
public class Item<T>
{
public readonly int ID;
public readonly T Data;
...
}
public void ProcessItem(Item<IFoo> item)
{
Console.WriteLine(item.ID);
}
ProcessItem(new Item<Foo>());
Classes in C# are invariant, so depending on your requirements you'll have to create an interface and implment that:
public interface IItem<out T> { ... }
public class Item<T> : IItem<T> { ... }
IItem<IFoo> item = new Item<Foo>();
Note that it is not necessarily safe to assign a Class<Subtype>
to a Class<Basetype>
. A common example is List<T>
:
List<object> l = new List<string>(); //won't compile
l.Add(3);
C# only allows variance annotations on interfaces and delegates, and only when it is safe to do so.
0 commentaires:
Enregistrer un commentaire