我有一个界面:
interface IInterface<T1, out T2> {};
,抽象类实现IInterface<>
abstract class AbsClass<T2> : IInterface<String, T2> {};
和其他抽象类继承自AbsClass<>
:
abstract class AbsAbsClassString : AbsClass<String, String> {};
abstract class AbsAbsClassTimeSpan : AbsClass<String, TimeSpan> {};
最后,
class CClassString1 : AbsAbsClassString {};
class CClassString2 : AbsAbsClassString {};
class CClassTimeSpan1 : AbsAbsClassTimeSpan {};
class CClassTimeSpan2 : AbsAbsClassTimeSpan {};
// and so on...
在我的C3代码中,我声明了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());
在每个list.Add(*)
句子上,编译器告诉我:
'System.Collections.Generic.ICollection(IInterface(String,object))的最佳重载方法匹配。添加(IInterface(String,object))'有一些无效的参数
参数1:无法将类型CClassString1隐式转换为IInterface(String,object)。存在显式转换(您是否错过了演员?)
如果我测试:
IInterface<String, Object> i;
CClassString1 cs1 = new CClassString1();
i = (Interface<String,Object>)cs1;
最后一句抛出一个异常,告诉它不可能进行演员表。
答案 0 :(得分:1)
通用接口协方差和逆变仅适用于引用类型。 TimeSpan
是一种值类型,因此IInterface<string, TimeSpan>
无法转换为IInterface<string, object>
。
那是因为变量强制转换是引用转换 - 它们不会更改对象的表示形式,它们只会更改引用的编译时类型。