При использовании перегруженных членов класса компилятору иногда приходится выбирать между несколькими функциями. Рассмотрим следующий пример:
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 компилятор всегда выбирает преобразование, изображенное сплошной линией, вместо пунктирных линий.
0 коммент.:
Отправить комментарий