我相信这很愚蠢,我有点不好意思问这种问题,但我仍然找不到答案:
我正在看课程List<T>
,它实现了IList
。
public class List<T> : IList
Ilist 中包含的方法之一是
int Add(object value)
我知道不List<T>
应该公开该方法(类型安全......),它确实没有。但怎么可能呢?类不能实现整个接口吗?
我相信这很愚蠢,我有点不好意思问这种问题,但我仍然找不到答案:
我正在看课程List<T>
,它实现了IList
。
public class List<T> : IList
Ilist 中包含的方法之一是
int Add(object value)
我知道不List<T>
应该公开该方法(类型安全......),它确实没有。但怎么可能呢?类不能实现整个接口吗?
我相信这个(接口)方法是明确实现的:
public class List<T> : IList
{
int IList.Add( object value ) {this.Add((T)value);}
}
通过这样做,该Add( object )
方法将被隐藏。List<T>
如果您将实例转换回实例,您将只能调用它IList
。
快速浏览反射器表明 IList.Add 是这样实现的:
int IList.Add(object item)
{
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item);
try
{
this.Add((T) item);
}
catch (InvalidCastException)
{
ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
}
return (this.Count - 1);
}
换句话说,实现将其强制转换为T以使其工作,并在您传入非T兼容类型时失败。
List<T>
显式实现IList.Add(object value)
,这就是它通常不可见的原因。您可以通过执行以下操作进行测试:
IList list = new List<string>();
list.Add(new SqlDataReader()); // valid at compile time, will fail at runtime
它显式地实现了它,因此您必须IList
先转换才能使用它。
List<int> l = new List<int>();
IList il = (IList)l;
il.Add(something);
您可以将其称为首先将列表实例转换为接口:
List<int> lst = new List<int>();
((IList)lst).Add("banana");
你会得到很好的运行时ArgumentException。
Frederik 是对的,对于某些成员,特别是那些对类型安全构成威胁的成员,它的实现是明确的List<T>
。IList
当然,他在回答中建议的实现不可能是正确的,因为它不会编译。
在这种情况下,典型的方法是做出勇敢的努力来尝试让接口成员工作,但如果不可能就放弃。
请注意,该IList.Add
方法定义为返回:
插入新元素的位置,或 -1 表示该项目未插入到集合中。
所以事实上,一个完整的实现是可能的:
int IList.Add(object value)
{
if (value is T)
{
Add((T)value);
return Count - 1;
}
return -1;
}
当然,这只是一个猜测。(如果您真的想确定,可以随时使用Reflector。)可能会略有不同;例如,它可以抛出一个NotSupportedException
,这通常用于不完整的接口实现,ReadOnlyCollection<T>
例如IList<T>
. 但由于以上符合 的记录要求IList.Add
,我怀疑它接近真实的东西。