Why explicit interface implementation?

后端 未结 2 1855
生来不讨喜
生来不讨喜 2020-12-06 07:02

I recently implemented a class like:

class TestClass : IDisposable
{
    RegistryKey m_key;
    public TestClass()
    {
        m_key = Registry.CurrentUser         


        
相关标签:
2条回答
  • 2020-12-06 07:19

    This is called explicit interface implementation. In your example since you define the Dispose() method as "void IDisposable.Dispose()" you are explicitly implementing the IDisposable interface as well.

    This is normally done to avoid collisions. If Microsoft ever wanted to add another Dispose() method that did something else to RegistryKey they wouldn't be able to unless they used explicit implementation of that interface.

    This is done often with the generic IEnumerable<T> interface. It requires you to also implement the non-generic interface IEnumerable. The only member in these two interfaces is GetEnumerator, with the generic one being more useful, so its usually implemented like this:

    public clas SomeClass : IEnumerable<SomeOtherClass>
    {
        public IEnumerator<SomeOtherClass> GetEnumerator ()
        {
            ...
        }
    
        IEnumerator IEnumerable.GetEnumerator ()
        {
            return GetEnumerator ();
        }
    }
    

    This way when you call an object of SomeClass's GetEnumator method, it calls the generic version, since the other one was implemented explicitly, allowing us to get the strong-typing generics allow.

    See pages 166-169 of Programming C# by Jesse Liberty (I've got the fourth edition).

    0 讨论(0)
  • 2020-12-06 07:30

    Most people don't agree with me, but I like using explicit interface implementation for all interfaces. I want to make it clear whether I'm writing a method to be called on my object or on my interface.

    This is painful if you have a reference to the object and want to call an interface method (like the above example), but I mitigate it by writing:

    class C : IDisposable
    {
        public IDisposable IDisposable { get { return this; } }
        void IDisposable.Dispose() { }
    }
    

    which means that calling the method on C looks like:

    C c = ...
    c.IDisposable.Dispose();
    

    The compiler parses this as "Call the IDisposable property on C, then call the Dispose() method on the result" but I read it as "Call the IDisposable.Dispose() method on C" which seems natural here.

    This approach can get ugly when using generic interfaces, unfortunately.

    0 讨论(0)
提交回复
热议问题