Search code examples
c#extension-methodsmultiple-inheritancemixins

Invoking interface extension methods from implementor is weird in C#


Invoking an extension method that works on a interface from an implementor seems to require the use of the this keyword. This seems odd.

Does anyone know why?

Is there an easier way to get shared implementation for an interface?

This irks me as I'm suffering multiple inheritance/mixin withdrawl.

Toy example:

public interface ITest
{
    List<string> TestList { get; }
}

public static class TestExtensions
{
    private const string Old = "Old";
    private const string New = "New";

    public static void ManipulateTestList(this ITest test)
    {
        for (int i = 0; i < test.TestList.Count; i++)
        {
            test.TestList[i] = test.TestList[i].Replace(Old, New);
        }
    }
}

public class Tester : ITest
{
    private List<string> testList = new List<string>();
    public List<string> TestList
    {
        get { return testList; }
    }

    public Tester()
    {
        testList.Add("OldOne");
        testList.Add("OldTwo");

        // Doesn't work
        // ManipulateTestList();

        // Works
        this.ManipulateTestList();
    } 
}

Solution

  • I asked this exact question to the language team directly. I don't have the e-mail to hand, but basically the answer (from Mads, IIRC) was that it is:

    • to reduce the search-space / complexity - i.e. not having to consider all available extension methods (and prune them) unless there is the expression first.
    • to reduce the chance of an extension method "taking over" a regular method (i.e. being a better match) unexpectedly

    Personally, I'd have liked it to work consistently - the first doesn't seem a big problem (but then, I don't write compilers), and neither approaches the fact that normally this.* is an optional thing (that may have influences such as local code style guidelines, i.e. "thou shalt use this.").