Reputation: 23277
I've a interface:
interface IInterface<T1, out T2> {};
and an abstract class implements IInterface<>
abstract class AbsClass<T2> : IInterface<String, T2> {};
and other abstract classes inherits from AbsClass<>
:
abstract class AbsAbsClassString : AbsClass<String, String> {};
abstract class AbsAbsClassTimeSpan : AbsClass<String, TimeSpan> {};
and finally,
class CClassString1 : AbsAbsClassString {};
class CClassString2 : AbsAbsClassString {};
class CClassTimeSpan1 : AbsAbsClassTimeSpan {};
class CClassTimeSpan2 : AbsAbsClassTimeSpan {};
// and so on...
In my C3 code, I've declared a List<IInterface<String, Object>>
IList<IInterface<String, Object>> list = new List<IInterface<String, Object>>();
list.Add(new CClassString1());
list.Add(new CClassString2());
list.Add(new CClassTimeSpan1());
list.Add(new CClassTimeSpan2());
On each list.Add(*)
sentence, compiler tells me:
The best overloaded method match for 'System.Collections.Generic.ICollection(IInterface(String,object)).Add(IInterface(String,object))' has some invalid arguments
Argument 1: Cannot implicitly convert type CClassString1 to IInterface(String,object). An explicit conversion exists (are you missing a cast?)
If I test with:
IInterface<String, Object> i;
CClassString1 cs1 = new CClassString1();
i = (Interface<String,Object>)cs1;
The last sentence throw an exception telling it's impossible to do the cast.
Upvotes: 0
Views: 431
Reputation: 14904
Generic interface convariance and contravariance only works with reference types. TimeSpan
is a value type, so IInterface<string, TimeSpan>
cannot be cast to IInterface<string, object>
.
That's because variant casts are reference conversions - they do not change the representation of the object, they only change the compile-time type of the reference.
Upvotes: 2