无法将类型“type”隐式转换为“type”

编译器要求显式转换。 例如,可能需要将右值转换成与左值相同的类型。 或者必须提供转换例程以支持某些运算符重载。

在将某个类型的变量赋给其他类型的变量时必须进行转换。 在不同类型的变量之间进行赋值时,编译器必须将赋值运算符右边的类型转换为赋值运算符左边的类型。 以下面的代码为例:

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 类型。 这是一个扩大转换,因为是从占用 4 个字节内存的类型 (int) 转换为占用 8 个字节内存的类型 (long)。 由于不会发生数据丢失,所以允许进行隐式扩大转换。 任何可存储于 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
  • 用户定义转换运算符
  •