Why can't I call methods within a class that explicitly implements an interface?
Asked Answered
F

4

45

Here's the story. I created an interface, IVehicle. I explicitly implemented the interface in my class, Vehicle.cs.

Here is my interface:

Interface IVehicle
{
        int getWheel();
}

here is my class:

class Vehicle: IVehicle
{

     public int IVehicle.getWheel()
     {
         return wheel;
     }

     public void printWheel()
     {
         Console.WriteLine(getWheel());
     }
}

Notice that getWheel() is explicitly implemented. Now, when I try to call that method within my Vehicle class, I receive an error indicating that getWheel() does not exist in the current context. Can someone help me understand what I am doing wrong?

Fugate answered 26/3, 2010 at 1:54 Comment(4)
AS a java person, I am wondering why this convoluted thing exists ? Why would anyone want the above to exist, what advantage does it gain ?Numismatology
Specifying a visibility modifier on an explicitely implemented member is a syntax error. The member is always accessible once your object has been casted to your interface type.Desdamonna
@mP If you are implementing multiple interfaces with a common member, this allows you to supply different definitions of it per interface. Also it adds to clean up intellisense, because the explicit members aren't visible or usable unless you cast to the proper interface.Buckels
To me it also adds to the code readability. Imagine a large class, where somewhere you have a putlic int Clean(int n) {...}. Is this an interface method or not? Can you just rename it, remove n, or you can't? With an explicit implementation you don't have to investigate - you see this at once.Catamnesis
N
53

When you explicitly implement the interface, you first have to cast the object to the interface, then you can call the method. In other words, the method is only available when the method is invoked on the object as the interface type, not as the concrete type.

class Vehicle: IVehicle {

     public int IVehicle.getWheel()
     {
         return wheel;
     }

     public void printWheel()
     {
         Console.WriteLine( ((IVehicle)this).getWheel() );
     }
}

See this reference at MSDN for more information. Here's the relevant snippet:

It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property access, or indexer access. An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.

For what it's worth -- this probably isn't a particularly good use of explicit interface implementation. Typically, you want to use explicit implementation when you have a class that has a full interface for typical operations but also implements an interface that may supersede some of those operations. The canonical example is a File class that implements IDisposable. It would have a Close() method but be required to implement Dispose(). When treating as a File you would use Open/Close. When opened in a using statement, however, it will treat it as an IDisposable and call Dispose. In this case Dispose simply calls Close. You wouldn't necessarily want to expose Dispose as part of the File implementation since the same behavior is available from Close.

Nellanellda answered 26/3, 2010 at 1:57 Comment(2)
Thanks. I only did it to prove to myself that I could do it. To this point, the book I am using didn't give any reason indicating the need to explicitly implement the interface.Fugate
Another common example of this is in the generated .Designer files of a winforms app. Every control is initialized between a pair of .BeginInit() and .EndInit() methods, but those calls are all made after casting the control to ISupportInitialize.Fill
B
13

According to MSDN:

It is possible to implement an interface member explicitly—creating a class member that is only called through the interface, and is specific to that interface.

And in the C# language specifications:

It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property access, or indexer access. An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.

To access this member you can first cast the class to the interface, and then access it.

Buckels answered 26/3, 2010 at 1:59 Comment(0)
G
4

To avoid a lot of boring casts on your class, you could create a pointer as the interface type

public class Foo : IBar
{
    readonly IBar bar;
    public Foo()
    {
       bar = this;
    }
}

And then call members using bar.

Gordon answered 24/4, 2015 at 5:19 Comment(0)
T
0

In your case it also might be that the "public" access modifier is not put in the function signature in the interface. Hence when you implement it in a class it only allows you to do so when the implementation is given the "private" access modifier. To fix this you should set the signature of the method in both the interface and the class to "public." As by default if you put no access modifier the function/member of the class is automatically set to "private"

Tassel answered 22/7, 2023 at 21:31 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Sugihara

© 2022 - 2024 — McMap. All rights reserved.