Как разрешение перегрузки группы метода отличается от разрешения перегрузки вызова метода?

Следующий код не компилирует (error CS0123: No overload for 'System.Convert.ToString(object)' matches delegate 'System.Converter<T,string>'):

class A<T> {
    void Method(T obj) {
        Converter<T, string> toString = Convert.ToString;

        // this doesn't work either (on .NET 4):
        Converter<object, string> toString2 = Convert.ToString;
        Converter<T, string> toString3 = toString2;            
    }
}

однако, это делает:

class A<T> {
    void Method(T obj) {
        // o is a T, and Convert.ToString(o) is using
        // string Convert.ToString(object o)

        Converter<T, string> toString = o => Convert.ToString(o);
    }
}

В c# 4, co/contra-variant делегаты может быть присвоен друг другу, и делегаты могут быть созданы из co/contra-variant методов, таким образом, ToString(object) метод может использоваться в качестве a Converter<T, string>, как T как всегда гарантируют, будет конвертируем к object.

Так, первый пример (разрешение перегрузки группы метода) должен находить единственный применимый метод string Convert.ToString(object o), то же как разрешение перегрузки вызова метода. Почему группа метода и разрешение перегрузки вызова метода приводящий к различным результатам?

6
задан thecoop 14 June 2010 в 11:40
поделиться

2 ответа

Это связано с тем, что дисперсия не применима к типам значений, поэтому если вы ограничите T как where T : class, то получите дисперсию на T и первый фрагмент кода скомпилируется.

Из FAQ по ковариации и контравариации:

Вариация поддерживается только если тип является ссылочным типом. Вариация не поддерживается для значений типов.

3
ответ дан 17 December 2019 в 18:10
поделиться

Второй код компилируется, потому что o является производным от объекта , поэтому очевидно, что вы можете вызвать метод, который принимает объект в качестве входных данных с помощью ] любой тип параметра .

Однако типы делегатов не равны . Если T не является объектом , сигнатуры методов не совпадают. Если, скажем, T равно int , у вас будет Converter , который не совпадает с Converter . Это два совершенно разных типа .

Вы столкнулись с проблемами, связанными с отсутствием в C # 3.0 согласованной / противоположной дисперсии. Должно быть лучше на C # 4.

0
ответ дан 17 December 2019 в 18:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: