53

If I have

public class AImplementation:IAInterface
{
   void IAInterface.AInterfaceMethod()
   {
   }

   void AnotherMethod()
   {
      ((IAInterface)this).AInterfaceMethod();
   }
}

How to call AInterfaceMethod() from AnotherMethod() without explicit casting?

Jader Dias
  • 88,211
  • 155
  • 421
  • 625
  • 3
    What is the problem with the cast? – adrianm Dec 08 '09 at 18:39
  • 1
    I just frowned when I discovered this language feature. It is very useful when implementing some interfaces like ICloneable though. – Jader Dias Dec 08 '09 at 21:06
  • 3
    Why not do it the other way around then? Move the code from the explicit interface method to a "normal" method. Then just let all methods (including the explicit interface method) call that method. – adrianm Dec 10 '09 at 07:16
  • IMHO, @adrianm's comment above is the best answer here! [And is a good refactoring when you encounter this situation, or if you expect to need this.] – ToolmakerSteve Jun 21 '18 at 01:12
  • FWIW in nearly all cases, one "workaround" is to change that one method to an *implicit* implementation, to allow internal access while satisfying the interface contract. The downside is that this is done by declaring the member `public` (and removing the explicit `IAInterface.` from declaration), which makes it more widely visible than you might want. So I'm *not recommending* this, just mentioning it as an alternative solution that is possible. – ToolmakerSteve Sep 21 '18 at 18:13
  • https://stackoverflow.com/q/1583050/1266873 -> casting is faster; so the code in the question will work faster than "as" operator. – Koray Sep 09 '22 at 06:22

8 Answers8

87

There are lots of ways of doing this without using the cast operator.

Technique #1: Use "as" operator instead of cast operator.

void AnotherMethod()   
{      
    (this as IAInterface).AInterfaceMethod();  // no cast here
}

Technique #2: use an implicit conversion via a local variable.

void AnotherMethod()   
{      
    IAInterface ia = this;
    ia.AInterfaceMethod();  // no cast here either
}

Technique #3: write an extension method:

static class Extensions
{
    public static void DoIt(this IAInterface ia)
    {
        ia.AInterfaceMethod(); // no cast here!
    }
}
...
void AnotherMethod()   
{      
    this.DoIt();  // no cast here either!
}

Technique #4: Introduce a helper:

private IAInterface AsIA => this;
void AnotherMethod()   
{      
    this.AsIA.IAInterfaceMethod();  // no casts here!
}
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 14
    To be pedantic, he didn't ask to not use the "cast operator", he asked for "without explicit casting", and I think that, generally speaking, operator `as` would be considered "explicit casting" (no idea if that's correct in terms of language spec definitions, or whether the question is even meaningless in that context). – Pavel Minaev Dec 08 '09 at 20:37
  • 2
    Well, the semantics of the cast operator and the semantics of the as operator are quite different, so it is a logical error to conflate them. See http://beta.blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx for details. – Eric Lippert Dec 08 '09 at 21:06
  • 10
    I know this is quite old, but I stumbled upon this question today. Am I correct to think the 'best' way is the implicit cast one? This offers the best compile time protection for the code am I correct? If I went either with casting or the "as" operation (which actually makes no sense in this context, since the object IS supposed to implement the interface in the first place) I run the risk of trying to cast to an invalid interface giving me a runtime error. If I try to implicit cast to an interface that the class does not implement, I get a compile time error instead, with is much better. – julealgon May 24 '13 at 14:14
  • 2
    @julealgon: You make a compelling argument. – Eric Lippert May 24 '13 at 15:45
  • I down voted because all the mentioned techniques ruin the call in case of inheritance i.e. if you are trying to call the method implementation from class A and the instance is of class B which inherits from class A then all the mentioned ways are going to call the B implementation. I do not know a way to call the A implementation without using the reflection. – Zverev Evgeniy Jan 10 '15 at 12:05
  • 1
    @zverev.eugene: If class B has re-implemented the interface then its implementation is *correct* for a receiver of type B; under what circumstances would you want to call the *wrong* method? The author of the more-derived class has more information than the author of the less-derived class, so the author of the more-derived class should decide what the semantics are. – Eric Lippert Jan 10 '15 at 20:20
  • 1
    @EricLippert: Consider class A (base class) implements interface I1 explicitly. Another class B inherits from class A and overrides I1 implementation i.e. implements it as well and needs to call base implementation (from class A). If A would implement I1 implicitly then that was not a problem (base.MethodDeclaredInI1). What do I do if the interface is implemented explicitly by class A? Reflection is my answer. Your answer is a good one. Append the case and it will be full. – Zverev Evgeniy Jan 12 '15 at 10:00
  • 7
    @zverev.Eugene: If the author of class `A` *intends* that a derived class must be able to call and/or override the base class implementation then the author of class `A` should make a protected virtual method rather than an explicit interface method. If the author of class `A` does not intend that, and the author of class `B` wishes that the author of class `A` had done so then the author of class `B` should either (1) find a different class to extend, perhaps by writing their own, or (2) negotiate with the author of class `A`. **Inheritance must be a designed-in feature of a class**. – Eric Lippert Jan 12 '15 at 17:19
  • The "What's the difference...?" blog post that Eric Lippert refers to in comments above is now at https://blogs.msdn.microsoft.com/ericlippert/2009/10/08/whats-the-difference-between-as-and-cast-operators/ – Peter Hull Mar 22 '16 at 14:27
10

You can introduce a helper private property:

private IAInterface IAInterface => this;

void IAInterface.AInterfaceMethod()
{
}

void AnotherMethod()
{
   IAInterface.AInterfaceMethod();
}
AndreasHassing
  • 687
  • 4
  • 19
Pavel Minaev
  • 99,783
  • 25
  • 219
  • 289
6

Tried this and it works...

public class AImplementation : IAInterface
{
    IAInterface IAInterface;

    public AImplementation() {
        IAInterface = (IAInterface)this;
    }

    void IAInterface.AInterfaceMethod()
    {
    }

    void AnotherMethod()
    {
       IAInterface.AInterfaceMethod();
    }
}
joshperry
  • 41,167
  • 16
  • 88
  • 103
2

And yet another way (which is a spin off of Eric's Technique #2 and also should give a compile time error if the interface is not implemented)

     IAInterface AsIAInterface
     {
        get { return this; }
     }
bjhuffine
  • 924
  • 1
  • 11
  • 23
  • I think this is better than Eric's technique #2 - IF you expect to need access to other interface method references in more than one method in the interface. – Matthew K. Crandall Apr 23 '19 at 19:52
0

The reason that this is not possible without an explicit or implicit cast may is, that you could implement more interfaces within the same class and all interfaces may provide the same method (same name and signature). Think about the following example:

class MyClass : IAInterface1, IAInterface2
{
   void IAInterface1.DoSomething() { }

   void IAInterface2.DoSomething() { }

   void AnotherMethod
   {
       this.DoSomething(); // ⚡ERROR
       // how should the compiler know which method to link?
   }
}

But the simples and in my opinion most elegant (and performant) solution for your use case is to provide two methods:

  • one is the actual implementation
  • two: the explicit interface implementation calling the first method
class MyClass : IAInterface
{
   void IAInterface.DoSomething() => this.DoSomething();

   private void DoSomething
   {
   }

   void AnotherMethod
   {
       this.DoSomething();
   }
}
rittergig
  • 715
  • 1
  • 5
  • 16
-1

You can't, but if you have to do it a lot you could define a convenience helper:

private IAInterface that { get { return (IAInterface)this; } }

Whenever you want to call an interface method that was implemented explicitly you can use that.method() instead of ((IAInterface)this).method().

helium
  • 1,077
  • 1
  • 9
  • 15
  • 1
    It's worth noting that you do not need an explicit cast here (since there is an implicit conversion from `this` to `IAInterface` which is implements). – Pavel Minaev Dec 08 '09 at 20:17
-2

Yet another way (not best):

(this ?? default(IAInterface)).AInterfaceMethod();
Viacheslav Ivanov
  • 1,535
  • 13
  • 22
  • 3
    Considering what the compiler does to make this work, this is merely a cumbersome way to say `((IAInterface)this)`, with the added downside that if `this` is `null`, and isn't supposed to be, it will call `AInterfaceMethod` on a default instance of your class, rather than throwing an exception. Almost certainly not wanted behavior. – ToolmakerSteve Jun 21 '18 at 01:03
-4

Can't you just remove the "IAInterface." from the method signature?

public class AImplementation : IAInterface
{
   public void AInterfaceMethod()
   {
   }

   void AnotherMethod()
   {
      this.AInterfaceMethod();
   }
}
Jader Dias
  • 88,211
  • 155
  • 421
  • 625
Lucas
  • 1,190
  • 8
  • 13