Collection<T> 不包含 ICollection 接口的所有属性

Collection<T> does not Contain the all properties of ICollection interface

Collection<T> class 实现了多个接口,其中之一是 ICollectionICollection 接口有 2 个未在 Collection<T>.

中实现的属性

在 C# 中,我相信您必须在继承接口的 class 中实现接口的所有方法和属性。那么 Collection<T> class 是如何逃脱惩罚的呢?

它的叔叔在框架上工作,每个人都在旁观。

Collection<T> 转换为 ICollection,您将看到它实现了 ICollection 的整个接口。

这叫做explicitly implementing an interface。除非对象引用转换为接口类型,否则您可以使成员对外部不可见。

Collection<T> 实现 ICollection 的上下文中,相关接口定义了在将泛型引入 C# 之前就存在的遗留方法。您可以说这是管理集合的 'old ugly' 方式。

实施者决定隐藏这些丑陋的方法,同时仍向调用者提供其功能。

var x = new Collection<int>();
object syncRoot = x.SyncRoot; //CS1061: Collection<int> does not contain a ....
ICollection collection = x;
syncRoot = collection.SyncRoot; //ok

另一种情况是冲突,通常是由于外部接口设计不好,无法更改。一个例子:

interface IFile
{
    void Save();
}
interface IDatabaseRecord
{
    void Save();
}

class Customer : IFile, IDatabaseRecord
{
    public void Save()
    {
        //what to do here?
    }
}

这可以通过显式实现方法来解决:

class Customer : IFile, IDatabaseRecord
{
    void IFile.Save() { }
    void IDatabaseRecord.Save() { }
}

请注意,这几乎总是代码异味 - 它可能会使调用者误以为方法不存在,或者调用了错误的实现(这导致首先发布了这个问题)。

阅读您的评论后,问题是这些属性是显式实现的,您可以注意到 here:

bool ICollection.IsSynchronized 
{
  get { return false; }
}

注意这不是常见的属性,例如:

public bool IsSynchronized 
{
  get { return false; }
}

这基本上意味着 属性 存在,但仅当您将其转换为 ICollection

var c = new Collection<double>();
var casted = (ICollection) c;
var isSync = casted.IsSynchronized;