Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю. Страница 64
Cannot implicitly convert type 'int' to 'short'. An explicit conversion exists (are you missing a cast?)
He удается неявно преобразовать тип int в short. Существует явное преобразование (возможно, пропущено приведение)
Проблема в том, что хотя метод
Add()
int
System.Int32
short,
short
Важно отметить, что все сужающие преобразования приводят к ошибкам на этапе компиляции, даже когда есть основание полагать, что такое преобразование должно пройти успешно. Например, следующий код также вызовет ошибку при компиляции:
// Снова ошибка на этапе компиляции!
static void NarrowingAttempt()
{
byte myByte = 0;
int myInt = 200;
myByte = myInt;
Console.WriteLine("Value of myByte: {0}", myByte);
}
Здесь значение, содержащееся в переменной типа
int(myInt)
byte
Если нужно проинформировать компилятор о том, что вы готовы мириться с возможной потерей данных из-за сужающей операции, тогда потребуется применить явное приведение, используя операцию приведения
()
Program
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with type conversions *****");
short numb1 = 30000, numb2 = 30000;
// Явно привести int к short (и разрешить потерю данных).
short answer = (short)Add(numb1, numb2);
Console.WriteLine("{0} + {1} = {2}",
numb1, numb2, answer);
NarrowingAttempt();
Console.ReadLine();
}
static int Add(int x, int y)
{
return x + y;
}
static void NarrowingAttempt()
{
byte myByte = 0;
int myInt = 200;
// Явно привести int к byte (без потери данных).
myByte = (byte)myInt;
Console.WriteLine("Value of myByte: {0}", myByte);
}
}
Теперь компиляция кода проходит успешно, но результат сложения оказывается совершенно неправильным:
***** Fun with type conversions *****
30000 + 30000 = -5536
Value of myByte: 200
Как вы только что удостоверились, явное приведение заставляет компилятор применить сужающее преобразование, даже когда оно может вызвать потерю данных. В случае метода
NarrowingAttempt()
byte
short
Main()
Для построения приложений, в которых потеря данных не допускается, язык C# предлагает ключевые слова
checked
unchecked
Использование ключевого слова checked
Давайте начнем с выяснения роли ключевого слова
checked
Program
byte
int
byte
static void ProcessBytes()
{
byte b1 = 100;
byte b2 = 250;
byte sum = (byte)Add(b1, b2);
// В sum должно содержаться значение 350.
// Однако там оказывается значение 94!
Console.WriteLine("sum = {0}", sum);
}
Удивительно, но при просмотре вывода приложения обнаруживается, что в переменной sum содержится значение 94 (а не 350, как ожидалось). Причина проста. Учитывая, что
System.Byte
sum