Неоднозначный вызов между перегрузками двухсторонних неявных кастируемых типов, когда производный тип единицы передается в качестве параметра

(Попытка найти название, которое суммирует проблему, может быть очень сложной задачей!)

У меня есть следующие классы с некоторыми перегруженными методами, которые вызывают ошибку компилятора неоднозначности вызова:

public class MyClass
{
    public static void OverloadedMethod(MyClass l) { }
    public static void OverloadedMethod(MyCastableClass l) { }

    //Try commenting this out separately from the next implicit operator. 
    //Comment out the resulting offending casts in Test() as well.
    public static implicit operator MyCastableClass(MyClass l)
    {
        return new MyCastableClass();
    }

    //Try commenting this out separately from the previous implicit operator.
    //Comment out the resulting offending casts in Test() as well.
    public static implicit operator MyClass(MyCastableClass l)
    {
        return new MyClass();
    }

    static void Test()
    {
        MyDerivedClass derived = new MyDerivedClass();
        MyClass class1 = new MyClass();
        MyClass class2 = new MyDerivedClass();
        MyClass class3 = new MyCastableClass();
        MyCastableClass castableClass1 = new MyCastableClass();
        MyCastableClass castableClass2 = new MyClass();
        MyCastableClass castableClass3 = new MyDerivedClass();

        OverloadedMethod(derived); //Ambiguous call between OverloadedMethod(MyClass l) and OverloadedMethod(MyCastableClass l)
        OverloadedMethod(class1);
        OverloadedMethod(class2);
        OverloadedMethod(class3);
        OverloadedMethod(castableClass1);
        OverloadedMethod(castableClass2);
        OverloadedMethod(castableClass3);

    }

public class MyDerivedClass : MyClass {  }

public class MyCastableClass { }

Следует отметить две очень интересные вещи:

Закомментирование любого из неявных операторных методов устраняет неоднозначность.Попытка переименовать первый перегруженный метод в VS приведет к переименованию первых четырех вызовов метода Test ()!

Это, естественно, ставит два вопроса:

Какова логика, лежащая в основе ошибки компилятора (т.е. как компилятор пришел к неоднозначности)?Что-то не так с этим дизайном? Интуитивно понятно, что двусмысленности не должно быть, и вызывающий сбой вызов должен быть разрешен при первой перегрузке метода (OverloadedMethod(MyClass l, MyClass r)) какMyDerivedClass более тесно связан сMyClass а не литье, но в остальном не имеет значенияMyCastableClass, Кроме того, рефакторинг VS, похоже, согласен с этой интуицией.

РЕДАКТИРОВАТЬ: После игры с рефакторингом VS я увидел, что VS сопоставляет вызов вызывающего метода с первой перегрузкой, определенной в коде, в зависимости от того, что это. Таким образом, если мы поменяемся местами между двумя перегрузками, VS сопоставит вызывающий вызов вызов сMyCastableClass параметр. Вопросы все еще актуальны, хотя.

Ответы на вопрос(2)

Ваш ответ на вопрос