List <t>如何实现Add(对象值)?</t>

时间:2010-12-08 14:48:54

标签: c# interface c#-2.0 explicit-interface

我认为这很愚蠢,我有点尴尬地问这个问题,但我仍然找不到答案:

我正在查看课程List<T>,该课程实现了IList

public class List<T> : IList

Ilist中包含的方法之一是

int Add(object value)

我理解List<T>不应该暴露那种方法(类型安全......),而事实并非如此。但它怎么可能呢? mustnt类实现整个界面吗?

6 个答案:

答案 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> IListint 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}}的记录要求,我怀疑它与实际情况接近。