我认为这很愚蠢,我有点尴尬地问这个问题,但我仍然找不到答案:
我正在查看课程List<T>
,该课程实现了IList
。
public class List<T> : IList
Ilist中包含的方法之一是
int Add(object value)
我理解List<T>
不应该暴露那种方法(类型安全......),而事实并非如此。但它怎么可能呢? mustnt类实现整个界面吗?
答案 0 :(得分:10)
我相信这个(接口)方法是implemented explicitly:
public class List<T> : IList
{
int IList.Add( object value ) {this.Add((T)value);}
}
通过隐藏,Add( object )
方法将隐藏。如果将List<T>
实例强制转换回IList
实例,则只能调用它。
答案 1 :(得分:3)
快速浏览反射器表明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 兼容类型时失败。
答案 2 :(得分:2)
List<T>
明确实现了IList.Add(object value)
,这就是为什么它通常不可见。您可以通过执行以下操作进行测试:
IList list = new List<string>();
list.Add(new SqlDataReader()); // valid at compile time, will fail at runtime
答案 3 :(得分:1)
它明确地实现了它,所以你必须先强制转换为IList
才能使用它。
List<int> l = new List<int>();
IList il = (IList)l;
il.Add(something);
答案 4 :(得分:1)
您可以先调用它将列表实例转换为接口:
List<int> lst = new List<int>();
((IList)lst).Add("banana");
你会得到很好的,运行时,ArgumentException。
答案 5 :(得分:1)
Frederik is right List<T>
IList
对int IList.Add(object value)
{
if (value is T)
{
Add((T)value);
return Count - 1;
}
return -1;
}
的实施对某些成员来说是明确的,特别是那些对类型安全构成威胁的成员。
他在答案中建议的实施当然是不对的,因为它不会编译。
在这种情况下,典型的方法是努力尝试以使接口成员工作,但如果不可能就放弃。
请注意,IList.Add
方法定义为返回:
新的位置 插入了元素,或-1到 表明该项目不是 插入集合中。
事实上,完整的实现 是可能的:
NotSupportedException
当然,这只是猜测。 (如果您确实想知道,可以随时使用Reflector。)可能会略有不同;例如,它可以抛出IList<T>
,这通常用于不完整的接口实现,例如ReadOnlyCollection<T>
的IList.Add
实现。但由于上述内容符合{{1}}的记录要求,我怀疑它与实际情况接近。