Search code examples
c#dictionaryinterface.net-6.0idictionary

How come Dictionary<TKey, TValue> has private interface methods?


While I was trying to implement the IDictionary<TKey, TValue> interface on one of my classes, I chose to delegate all the interface methods of IDictionary<TKey, TValue> to an instance of Dictionary<TKey, TValue> that I had instantiated in my class. Then, I was quite confused that the IDE complained that I was trying to access private methods of Dictionary<TKey, TValue>. However, these methods are ought to be part of the IDictionary<TKey, TValue> interface! How can they be private? I checked the source code of Dictionary<TKey, TValue> and indeed it has a private implementation of CopyTo. How am I supposed to delegate CopyTo and how is it even possible for an interface method to be private in the first place?

The IDE says that CopyTo is private in the following code.

public abstract class BindingCollectionTemplate<TName, TValue>: ScopeTemplate, IDictionary<TName, TValue>
{
    private readonly Dictionary<TName, TValue> dictionary = new();
    // ...
    public void CopyTo(KeyValuePair<TName, TValue>[] array, int arrayIndex)
    {
        dictionary.CopyTo(array, arrayIndex); // Accessing a private interface method??
    }
    // ...
}

Solution

  • This method comes from ICollection<T> interface and dictionary implements it:

    public interface IDictionary<TKey,TValue>
     : ICollection<KeyValuePair<TKey,TValue>>, ... 
    

    In dictionary this method is implemented via an explicit interface implementation which uses the private CopyTo:

    void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(
        KeyValuePair<TKey, TValue>[] array, 
        int index) => CopyTo(array, index);
    

    So you can access it via interface:

    class MyDict<TKey, TValue> : IDictionary<TKey, TValue>
    {
        private Dictionary<TKey, TValue> _internal = new Dictionary<TKey, TValue>();
        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) =>
            ((IDictionary<TKey, TValue>)_internal).CopyTo(array, arrayIndex);
    }