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