Ошибка компилятора CS0029
Не удается неявно преобразовать тип "type" в "type"
Компилятору требуется явное преобразование. Например, может потребоваться приведение r-значения к тому же типу, который имеет l-значение. Или может быть необходимо предоставить подпрограммы преобразования для поддержки перегрузки определенных операторов.
Преобразование должно выполняться в том случае, когда переменная одного типа присваивается переменной другого типа. При присвоении между переменными разных типов компилятор должен преобразовать тип в правой части оператора присваивания в тип в его левой части. Рассмотрим следующий код:
int i = 50;
long lng = 100;
i = lng;
i = lng;
выполняет присваивание, однако типы данных переменных в левой и правой частях оператора присваивания не совпадают. Перед назначением компилятор неявно преобразует переменную lng
, которая имеет тип long, в int. Это неявно, так как код явно не поручил компилятору выполнить это преобразование. Обратите внимание, что в этом коде реализуется неявное сужающее преобразование, которое не допускается компилятором из-за риска потери данных.
Преобразование является сужающим в тех случаях, когда целевой тип данных занимает в памяти меньше места, чем исходный. Например, сужающим является преобразование из long в int. Тип long занимает в памяти 8 байт, а тип int — 4 байта. Ниже показан пример потери данных в результате такого преобразования:
int i = 50;
long lng = 3147483647;
i = lng;
Переменная lng
содержит слишком большое значение, которое нельзя сохранить в переменной i
. Таким образом, при преобразовании этого значения в тип int потеряется часть данных, а преобразованное значение не будет в точности равно исходному.
Расширяющие преобразования являются противоположностью сужающих. В этом случае целевой тип данных занимает в памяти больше места, чем исходный. Ниже приведен пример расширяющего преобразования:
int i = 50;
long lng = 100;
lng = i;
Обратите внимание на отличие этого примера кода от первого. На этот раз переменная lng
находится в левой части оператора присваивания и является его целевой переменной. Перед присвоением компилятор должен неявно преобразовать переменную i
типа int в тип long. Это будет расширяющее преобразование, поскольку исходный тип (int) занимает в памяти 4 байта, а целевой (long) — 8 байт. Неявные расширяющие преобразования не связаны с риском потери данных и допускаются к применению. Любое значение типа int может быть сохранено в переменной типа long.
Поскольку неявные сужающие преобразования не допускаются, для успешной компиляции этого кода необходимо явно выполнить преобразование типа данных. Явные преобразования выполняются путем приведения типов. Понятие приведения типов в языке C# описывает преобразование одного типа в другой. Чтобы гарантировать успешную компиляцию кода, необходимо использовать следующий синтаксис:
int i = 50;
long lng = 100;
i = (int) lng; // Cast to int.
В третьей строке кода содержится инструкция для явного преобразования переменной lng
типа long в тип int перед выполнением присвоения. Помните, что при сужающем преобразовании существует риск потери данных. Сужающие преобразования следует использовать с осторожностью, поскольку даже в случае успешной компиляции кода во время выполнения могут быть получены непредвиденные результаты.
Приведенная здесь информация относится только к типам значений. При использовании типов значений вы работаете напрямую с данными, хранящимися в переменной. Но в .NET также есть ссылочные типы. В случае с ними вы работаете не с фактическими данными, а со ссылками на переменные. Например, к ссылочным типам относятся классы, интерфейсы и массивы. Неявные или явные преобразования между ссылочными типами не поддерживаются кроме случаев, когда компилятор допускает конкретные преобразования или реализованы соответствующие операторы преобразования.
В следующем примере возникает ошибка CS0029:
// CS0029.cs
public class MyInt
{
private int x = 0;
// Uncomment this conversion routine to resolve CS0029.
/*
public static implicit operator int(MyInt i)
{
return i.x;
}
*/
public static void Main()
{
var myInt = new MyInt();
int i = myInt; // CS0029
}
}
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по