Метод перегрузки.Как это работает? - PullRequest
11 голосов
/ 05 января 2012

Предположим, у меня есть эти две перегруженные функции.

public static void Main(string[]args)
{
     int x=3;
     fn(x); 
}

static void fn(double x)
{ 
    Console.WriteLine("Double");
}

static void fn(float x)
{
    Console.WriteLine("Float");
}

Почему компилятор выберет функцию с плавающей запятой?

Ответы [ 2 ]

22 голосов
/ 05 января 2012

Он соответствует правилам раздела 7.5.3.2 спецификации C # 4.

int неявно преобразуется в float и double, поэтому оба метода-кандидата применимы .Однако преобразование из int в float "лучше, чем" преобразование из int в double в соответствии с разделом 7.5.3.2-7.5.3.5:

Учитывая два разныхтипов T1 и T2, T1 является лучшей целью преобразования, чем T2, если выполняется хотя бы одно из следующих условий:

  • Неявное преобразование из T1 в T2 существует, и неявное преобразование из T2 в T1 не существует
  • ... [в данном случае не имеет значения]

Здесь есть неявное преобразование из float в double, но неявное преобразование из double вfloat - так что float является лучшей целью конверсии, чем double.

11 голосов
/ 05 января 2012

Ответ Джона, конечно, правильный. Чтобы добавить немного больше деталей: принцип дизайна здесь заключается в том, что «более конкретный» метод лучше. Если у вас было:

void M(object x){}
void M(Animal x){}
void M(Giraffe x){}

и вы позвонили M(new Giraffe()), очевидно, вы бы хотели точное совпадение. Если вы назвали M(new Tiger()), лучшим совпадением будет «Животное», потому что тигр - это разновидность животного, тигр - это разновидность объекта, а животное - точнее , чем объект. Откуда мы знаем, что животное более специфично, чем объект? Поскольку каждое животное является объектом, но не каждый объект является животным, животное должно быть более конкретным.

Если бы вы позвонили M(null), мы бы выбрали версию с жирафом. Жираф более специфичен, чем Животное, потому что каждый жираф - это животное, но не каждое животное - это жираф.

В вашем примере, float лучше, чем double, потому что он более конкретен. Каждый float может быть преобразован в double, но не каждый double может быть преобразован в float, поэтому float более конкретен. Подобно тому, как каждое животное может быть преобразовано в объект, но не каждый объект может быть преобразовано в животное, так и животное более конкретно.

...