Преобразования и идентификация функций класса

При использовании перегруженных членов класса компилятору иногда приходится выбирать между несколькими функциями. Рассмотрим следующий пример:

using System;

class Conv

{

public static void Process(sbyte value)

{

Console.WriteLine("sbyte {0}", value);

}

public static void Process(short value)

{

Console.WriteLine("short {0}", value);

}

public static void Process(int value)

{

Console.WriteLine("int {0}", value);

}

}

class Test

{

public static void Main()

{

int value1 = 2;

sbyte value2 = 1;

Conv.Process(value1);

Conv.Process(value2);

}

}

Программа выводит следующий результат:

int 2

sbyte 1

При первом вызове Process() компилятор находит совпадение с параметром int лишь в одной из функций — той, которая получает параметр типа int.

Однако при втором вызове компилятору приходится выбирать одну из трех функций, получающих параметры типа sbyte, short и int. Чтобы выбрать одну из версий, компилятор сначала пытается выполнить точное сопоставление типа. В данном примере он находит функцию с параметром типа sbyte, поэтому будет вызвана именно эта версия. При отсутствии этой функции была бы выбрана функция с параметром short, потому что тип short может быть неявно преобразован в int. Другими словами, тип short расположен «ближе» к sbyte в иерархии преобразований, поэтому предпочтение отдается именно ему.

Это правило подходит для многих случаев, но в следующем примере оно не поможет:

using System;

class Conv

{

public static void Process(short value)

{

Console.WriteLine("short {0}", value);

}

public static void Process(ushort value)

{

Console.WriteLine("ushort {0}", value);

}

}

class Test

{

public static void Main()

{

byte value = 3;

Conv.Process(value);

}

}

На этот раз описанное правило не позволяет компилятору отдать предпочтение одной функции перед другой, поскольку между ushort и short не существует неявных преобразований.

В этом случае в игру вступает другое правило, которое гласит, что при наличии неявного преобразования к знаковому типу (изображенного на рисунке сплошной линией) ему следует отдать предпочтение перед всеми преобразованиями к беззнаковым типам (пунктирные линии). В иерархии на рис. 15.1 компилятор всегда выбирает преобразование, изображенное сплошной линией, вместо пунктирных линий.

Предлагаю ознакомиться с аналогичными статьями: