ОБНОВЛЕНИЕ: Начиная с C # 7.3, это больше не должно быть проблемой.Из примечаний к выпуску:
Когда группа методов содержит несколько общих методов, аргументы типа которых не удовлетворяют их ограничениям, эти члены удаляются из набора кандидатов.
Pre C # 7.3:
Итак, я прочитал Эрик Липперт «Ограничения не являются частью подписи» , и теперь я понимаю, что спецификация определяет, что ограничения типа проверяются ПОСЛЕразрешение перегрузки, но я до сих пор не понимаю, почему это должно иметь место.Ниже приведен пример Эрика:
static void Foo<T>(T t) where T : Reptile { }
static void Foo(Animal animal) { }
static void Main()
{
Foo(new Giraffe());
}
Это не компилируется, потому что разрешение перегрузки для: Foo(new Giraffe())
предполагает, что Foo<Giraffe>
является лучшим соответствием перегрузки, но тогда ограничения типа не выполняются, и ошибка времени компиляциивыброшены.По словам Эрика:
Принцип здесь - это разрешение перегрузки (и вывод типа метода), чтобы найти наилучшее возможное совпадение между списком аргументов и списком формальных параметров каждого метода-кандидата.То есть они смотрят на сигнатуру метода-кандидата.
Типовые ограничения НЕ являются частью подписи, но почему они не могут быть?В каких сценариях считается плохой идеей считать ограничения типов частью сигнатуры? Это просто сложно или невозможно реализовать?Я не защищаю то, что, если по какой-либо причине невозможно выбрать наилучшую перегрузку, молча отступите ко второму.Я бы ненавидел это.Я просто пытаюсь понять, почему ограничения типа не могут быть использованы для влияния на выбор наилучшей перегрузки.
Я представляю, что внутри компилятора C #, только для разрешения перегрузки (метод не переписывается навсегда) , следующее:
static void Foo<T>(T t) where T : Reptile { }
преобразуется в:
static void Foo(Reptile t) { }
Почему вы не можете "вытянуть"ограничения типа в формальном списке параметров?Как это меняет подпись каким-либо образом?Я чувствую, что это только укрепляет подпись.Тогда Foo<Reptile>
никогда не будет считаться кандидатом на перегрузку.
Редактировать 2: Неудивительно, что мой вопрос был настолько запутанным.Я не читал должным образом блог Эрика и привел неправильный пример.Я отредактировал в примере, который я считаю более подходящим.Я также изменил название, чтобы быть более конкретным.Этот вопрос не кажется таким простым, как я впервые себе представлял, возможно, мне не хватает какой-то важной концепции.Я менее уверен, что это материал для работы со стеком, возможно, лучше перенести этот вопрос / обсуждение в другое место.