-1

I have two Interfaces A,B (residing in different components). Both declare a method with the same signature ( MyMethod ). The two interfaces are inherited by a third Interface (C).

The method which is declared in the first two interfaces (A,B) is intended to return always the same values (for A and B) and thus, I don’t want to implement the interfaces explicitly when deriving from C.
I achieve this with declaring the method also in the third interface, while using the new-keyword.

public interface A {
   MyType MyMethod();
}
public interface B {
   MyType MyMethod();
}

public interface C : A,B{
   new MyType MyMethod();
}

public class ImplementingClass : C{
   public MyType MyMethod(){
       // do somethin
       // return something
   }
}

Are there problems to be expected with this, or is this bad style?

Update
Sorry, my initial question has not shown the full story. The Problem arises, when I try to call MyMethod on a interface-reference of C. The Compiler will not compile this.

 C aReferenceToC=new CImplementingClass();
 aReferenceToC.MyMethod(); // <<< Here the compiler will throw an exception

Full example

C myCImplementationAsAnInterfaceReference = new MyCImplementation(); 
myCImplementationAsAnInterfaceReference.MyMethod(); // This does not compile without declaring MyMethod in C with the new-Keyword

MyCImplementation myCImplementationReference= new MyCImplementation(); 
myCImplementationReference.MyMethod(); // This however will always compile and run

public interface A {
        int MyMethod();
}
public interface B {
        int MyMethod();
}

public interface C : A, B {

}

public class MyCImplementation : C {

        public int MyMethod() {
            return 1;
        }
}
HCL
  • 36,053
  • 27
  • 163
  • 213
  • -1 This belongs in programmers.stackexchange (just kidding) - good question though. – Aniket Inge Feb 01 '13 at 14:25
  • I just tried this and any class implementing this will only ever implement one method, thus the one being called will be random? – Dr Schizo Feb 01 '13 at 14:33
  • @HCL With your full example, you are correct. You can't use the type as C unless you plug in your new MyType MyMethod(); in interface C. I am curious as to why your two base interfaces have the same method signature. – Aaron Hawkins Feb 01 '13 at 15:25
  • @Aaron: It's a sort of multiple inheritance where A and B provide meta-data about the same object (in two different libraries), but from another perspectives. MyMethod returns the data-type represented by this object, and the data type is always the same. C unions A and B and is used in the application. – HCL Feb 01 '13 at 15:34
  • @HCL What are the two different libraries? Are A and B identical? – Aaron Hawkins Feb 01 '13 at 15:42
  • Why not just call it MyMethodC in interface C? Really it still returns MyType. – paparazzo Feb 01 '13 at 15:48
  • Or could you get there with having A and B each implement C? In that case C would just intersect A and B. – paparazzo Feb 01 '13 at 15:52
  • @Aaron: No, A is much lower level and provides other services. – HCL Feb 01 '13 at 16:02
  • @Blam: To not having 3 Methods on class returning the always same value. C is on a higher level. – HCL Feb 01 '13 at 16:03
  • An interface defines the type not value. Even if it complied it would not require A and B to return the same value to the same inputs. – paparazzo Feb 01 '13 at 16:43
  • @blam: Not sure if I understand your comment. To clarify: C implements A and B, not the other way round. Look at the answer from Jeppe, it make things clear. Sorry for the mess I have created, I was initialy not aware that the problem only arises while using interface-references. Combined with my poor English skills that has led to a great confusion. Thanks anyway for your time and sorry! – HCL Feb 01 '13 at 17:03

2 Answers2

1

Doing what you do, does not in any way stop people from giving different implementations of A.MyMethod, B.MyMethod, and C.MyMethod.

  class TestABC : C
  {
    MyType C.MyMethod()
    {
      // 1
      return null;
    }

    MyType A.MyMethod()
    {
      // 2
      return null;
    }

    MyType B.MyMethod()
    {
      // 3
      return null;
    }
  }

The new keyword does not in anyway remove the "hidden" method. It just tells the compiler to tolerate the fact that the type has now two identical methods with the same signature, one inherited from a base type, and one declared by the current type.

Edit: OK, given the development of your question, here's what I think your problem really was (this wasn't clear to me initially):

You had this design:

public interface A {
   MyType MyMethod();
}
public interface B {
   MyType MyMethod();
}

public interface C : A,B{
}

Your problem was that this code didn't compile:

C myInstance = CreateAnInstanceOfSomeClassImplementingC();
myInstance.MyMethod();  //  does not compile, ambiguous

Your question is if it's an OK solution to get rid of the compiler error error CS0121: The call is ambiguous between the following methods or properties: [...] by introducing the new member in C.

To me it seems ugly. But i cannot come up with another solution (when you informed me in the comments that C could not be a class). There's no way for an interface to dictate that two methods inherited must unite.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
  • I dont want to stop people to provide explicit implementations of MyMethod. I want to avoid that people must explicitly cast to A or B if they want to call MyMethod on a class which implements C. – HCL Feb 01 '13 at 14:52
  • 1
    @HCL That's a noticeably different code snippet than you started with, and you never said that you were getting a compiler error before. This is what happens when you omit lots of important information in your question. – Servy Feb 01 '13 at 15:14
  • @Servy Yes, I'm very sorry for this, at the time I posted my question, I have not realized that the problem arises only when I'm using reference of the interface type, but not with the implementing types. It's clearly my fault. Sorry! – HCL Feb 01 '13 at 15:18
  • @HCL OK, so you want the two different methods to **unite** in `C`? There's no real syntax for that. Your "solution" is to introduce a third method in `C` which will have highest "priority" when overload resolution sets in. It's kind of a hack. Is it possible to change `C` from an `interface` to an `abstract class`? Because then you can have the two methods unite in an abstract public method of the abstract class. That would be more "clean" in my opinion. (But it still doesn't prevent people from implementing `A` and/or `B` again while deriving from the abstract class.) – Jeppe Stig Nielsen Feb 01 '13 at 15:28
  • @JeppeStigNielsen: No, an abstract base-class is not an option. Many objects will implent C, having already other inheritance. – HCL Feb 01 '13 at 15:43
-1

Whether using new keyword or not does not really change anything here. the behavior is just the same.

Testing testing = new Testing();
testing.MyMethod(); // calls Testing.MyMethod

AA testingA = new Testing();
testingA.MyMethod(); // calls AA.MyMethod


 public interface A
{
    int MyMethod();
}

public class AA : A
{

    public int MyMethod()
    {
        return 11;
    }
}

public interface B
{
    int MyMethod();
}

public interface C : A, B
{
    int MyMethod();
}

public class Testing : AA,C
{
    public int MyMethod()
    {
        return 10;
    }
}
daryal
  • 14,643
  • 4
  • 38
  • 54