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

4

Collection<T>类实现了多个接口,其中一个是ICollectionICollection接口有2个属性在Collection<T>中没有实现。

在C#中,我认为您必须在继承它的类中实现接口的所有方法和属性。那么Collection<T>类如何逃脱呢?


3
Google "Explicit Interface Member Implementation" 翻译为:显式接口成员实现 - chomba
1
你为什么说这些属性没有被实现?我在这里看到了它们:http://referencesource.microsoft.com/#mscorlib/system/collections/objectmodel/collection.cs,281923b8611114ec。ICollection请求的属性包括Count、SyncRoot和IsSynchronized,它们都已经被包含了。 - bto.rdz
1
你认为哪两个属性没有被实现? - hatchet - done with SOverflow
FYI。接口强制实现但不限制访问级别。许多 MS 库使用“internal”访问修饰符实现接口。 - MDK
2
@MDK,你能给个具体的例子吗?如果一个类实现了一个公共接口,那么与该接口相关的所有方法都必须是公共的。 - D Stanley
显示剩余3条评论
3个回答

7
这被称为显式实现接口。你可以使成员在对象引用转换为接口类型之前对外不可见。
在实现ICollectionCollection<T>上下文中,所涉及的接口定义了在泛型引入到C#之前存在的遗留方法。你可以说这是管理集合的“老旧丑陋”方式。
实现者决定隐藏这些丑陋的方法,同时仍向调用者提供其功能。
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() { }
}

请注意,这几乎总是一个代码异味 - 这可能会让调用者误以为找不到一个方法,或调用错误的实现(这也是最初发布这个问题的原因)。

谢谢您解释它及其用途。最后一个问题,虽然我想不到用途,但我们能否创建一个接口并以类似的方式隐藏一些属性或方法。 - Abhi.Net
接口没有访问修饰符,它基本上是这样的。因此,不可能隐藏成员。 - Bas
@Abhi.Net,我认为它们实际上并不是隐藏的。如果你有一个接受上述情景中的IFile的方法,并且将Customer的实例传递给它,那么类型为IFile的参数将具有一个Save()方法。更重要的是,它将调用IFile.Save(),如果我没有记错的话。 - Royal Bg

2

在阅读了您的评论后,问题是这些属性是显式实现的,正如您可以在这里看到的那样:

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;

最后一个问题,你有没有想过为什么在Visual Studio中看到Collection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable,而在那个链接中是Collection<T>: IList<T>, IList, IReadOnlyList<T>? - Abhi.Net
@Abhi.Net 用我给你的 oink 玩耍,使用搜索框并单击任何类型或接口以查看其定义,这对我非常有帮助。 - bto.rdz

1
它的叔叔在框架公司工作,每个人都视而不见。
Collection<T>转换为ICollection,你会发现它实现了整个ICollection接口。

“它的叔叔为框架工作,每个人都视而不见”这句话是什么意思?我相信一定有更好的解释。 - Abhi.Net
裙带关系和阶级区别。 - Scott Hannen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接