I defined a generic method Use<T> in an interface IInterface. I tried to make an implementation of that interface where the concrete implementation of the Use<T> method depends on the actual type T, and I want to always call the most specialized method. But it does not work:
    interface IInterface { void Use<T>(T other) where T : IInterface; }
    interface IChildInterface : IInterface { }
    class ImplementsIInterface : IInterface
    {
        public void Use<T>(T other) where T : IInterface
        {
            Debug.WriteLine("ImplementsInterface.Use(IInterface)");
        }
    }
    class ImplementsChildInterface : IChildInterface
    {
        public void Use<T>(IChildInterface other) where T : IInterface
        { // idea: if other is IChildInterface, use this method
            Debug.WriteLine("ImplementsChildInterface.Use(IChildInterface)");
        }
        public void Use<T>(T other) where T : IInterface
        { // idea: if above method is not applicable, use this method
            Debug.WriteLine("ImplementsChildInterface.Use(IInterface)");
        }
    }
Here is my main method:
    public static void Main()
    {
        IChildInterface childinterf = new ImplementsChildInterface();
        childinterf.Use(new ImplementsChildInterface()); // outputs "ImplementsChildInterface.Use(IInterface)"
                                                         // but should output "ImplementsChildInterface.Use(IChildInterface)"
        childinterf.Use(new ImplementsIInterface());     // outputs "ImplementsChildInterface.Use(IInterface)"
    }
The method that takes an IChildInterface argument is never called, although it should.
Is there a way to make this work? Or is my approach fundamentally wrong?
Note that it is a necessity that IInterface only has one method definition. I might enlarge the interface hierarchy at any time (and thus increase the number of implementations I could provide in an implementing class), but this should not lead to needing to add more method definitions in IInterface. Otherwise, the whole point of using interfaces (i.e. to be flexible) would be missed.
The answers I got so far all involve the need to cast. This is also something I don't want to do, since it makes the whole setup useless. Let me explain the broader picture of what I try to achieve:
Let's imagine we created some instance of an IInterface (like so: IInterface foo = new ImplementsChildInterface();). It will behave in a certain way, but it will always behave in the same way - no matter if we see it as an IInterface, an IChildInterface or an ImplementsChildInterface. Because, if we call some method on it, the compiler (or runtime? i don't know) will check what type it REALLY is and run the method defined in that type.
Now imagine we have two instances i1 and i2 of IInterface. They again are, under the hood, concrete implementations of IInterface, so they have a concrete behaviour, no matter through which glasses we seem them.
So when I run i1.Use(i2), the compiler (or runtime?) should be able to find out what i1 and i2 REALLY are, and run the corresponding method. Like so:
- Which type does 
i1have?ImplementsChildInterface, ok, then I'll look at the methods there. - Which type does 
i2have?ImplementsIInterface, ok, then let's see if there exists a methodUse(ImplementsIInterface ...). There is none, but maybe there is a fallback?ImplementsIInterfaceis aIInterface, so let's see if there exists a methodUse(IInterface ...). Yes, it exists, so let's call it! 
                        
Neither
IInterfacenorIChildInterfacehave a memberUse<T>(IChildInterface other)defined, but onlyUse<T>(T other).Your class
ImplementsChildInterfaceon the other side has a methodUse<T>(IChildInterface other). As you declaringchildInterfas a reference of typeIChildInterfaceyou can´t access that member, but unly those defined in the interface. So you should cast to the actual class in order to access the method accepting an instance ofIChildInterface. But even then the generic implementation is used. So you should also cast your parameter toIchildInterface:Furthermore as you don´t use the generic type-parameter within your more specialized method, you can also omit it:
Alternativly you may also add a method into your
IChildInterface:Now you can use
which will print the desired output.