InvalidCastException 类

定义

当执行了无效的强制转换或显式转换时引发的异常。

public ref class InvalidCastException : Exception
public ref class InvalidCastException : SystemException
public class InvalidCastException : Exception
public class InvalidCastException : SystemException
[System.Serializable]
public class InvalidCastException : SystemException
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class InvalidCastException : SystemException
type InvalidCastException = class
    inherit Exception
type InvalidCastException = class
    inherit SystemException
[<System.Serializable>]
type InvalidCastException = class
    inherit SystemException
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type InvalidCastException = class
    inherit SystemException
Public Class InvalidCastException
Inherits Exception
Public Class InvalidCastException
Inherits SystemException
继承
InvalidCastException
继承
InvalidCastException
属性

注解

.NET Framework支持从派生类型自动转换为其基类型并返回到派生类型,以及从呈现接口对象和后退接口的类型。 它还包括支持自定义转换的各种机制。 有关详细信息,请参阅.NET Framework中的类型转换

InvalidCastException当不支持将一种类型的实例转换为另一种类型时,将引发异常。 例如,尝试将值DateTime转换为Char值会InvalidCastException引发异常。 它不同于异常,当支持将一种类型转换为另一 OverflowException 种类型时,会引发异常,但源类型的值不在目标类型的范围内。 异常 InvalidCastException 是由开发人员错误引起的,不应在块中 try/catch 处理。 相反,应消除异常的原因。

有关系统支持的转换的信息,请参阅该 Convert 类。 对于当目标类型可以存储源类型值但不足以存储特定源值时发生的错误,请参阅 OverflowException 异常。

备注

在许多情况下,语言编译器检测到源类型和目标类型之间不存在转换,并发出编译器错误。

以下各节讨论了尝试转换引发 InvalidCastException 异常的一些条件:

要使显式引用转换成功,源值必须是 null,或者源参数引用的对象类型必须通过隐式引用转换转换为目标类型。

以下中间语言 (IL) 指令引发 InvalidCastException 异常:

  • castclass

  • refanyval

  • unbox

InvalidCastException 使用具有值0x80004002的 HRESULT COR_E_INVALIDCAST。

有关实例的初始属性值的列表InvalidCastException,请参阅InvalidCastException构造函数。

基元类型和 IConvertible

直接或间接调用不支持特定转换的 IConvertible 基元类型的实现。 例如,尝试将值转换为或DateTimeChar将值转换为BooleanInt32引发InvalidCastException异常。 以下示例调用 Boolean.IConvertible.ToChar 值和 Convert.ToChar(Boolean) 方法,以将值转换为 BooleanChar。 在这两种情况下,方法调用都引发异常 InvalidCastException

using System;

public class Example
{
   public static void Main()
   {
      bool flag = true;
      try {
         IConvertible conv = flag;
         Char ch = conv.ToChar(null);
         Console.WriteLine("Conversion succeeded.");
      }
      catch (InvalidCastException) {
         Console.WriteLine("Cannot convert a Boolean to a Char.");
      }

      try {
         Char ch = Convert.ToChar(flag);
         Console.WriteLine("Conversion succeeded.");
      }
      catch (InvalidCastException) {
         Console.WriteLine("Cannot convert a Boolean to a Char.");
      }
   }
}
// The example displays the following output:
//       Cannot convert a Boolean to a Char.
//       Cannot convert a Boolean to a Char.
open System

let flag = true
try
    let conv: IConvertible = flag
    let ch = conv.ToChar null
    printfn "Conversion succeeded."
with :? InvalidCastException ->
    printfn "Cannot convert a Boolean to a Char."

try
    let ch = Convert.ToChar flag
    printfn "Conversion succeeded."
with :? InvalidCastException ->
    printfn "Cannot convert a Boolean to a Char."

// The example displays the following output:
//       Cannot convert a Boolean to a Char.
//       Cannot convert a Boolean to a Char.
Module Example
   Public Sub Main()
      Dim flag As Boolean = True
      Try
         Dim conv As IConvertible = flag
         Dim ch As Char = conv.ToChar(Nothing)
         Console.WriteLine("Conversion succeeded.")
      Catch e As InvalidCastException   
         Console.WriteLine("Cannot convert a Boolean to a Char.")
      End Try
      
      Try
         Dim ch As Char = Convert.ToChar(flag)
         Console.WriteLine("Conversion succeeded.")
      Catch e As InvalidCastException   
         Console.WriteLine("Cannot convert a Boolean to a Char.")
      End Try
   End Sub
End Module
' The example displays the following output:
'       Cannot convert a Boolean to a Char.
'       Cannot convert a Boolean to a Char.

由于不支持转换,因此没有解决方法。

Convert.ChangeType 方法

已调用 Convert.ChangeType 该方法将对象从一种类型转换为另一种类型,但一种或两种类型都未实现 IConvertible 接口。

在大多数情况下,由于不支持转换,因此没有解决方法。 在某些情况下,可能的解决方法是将源类型中的属性值手动分配给目标类型的类似属性。

缩小转换范围和 IConvertible 实现

缩小运算符定义类型支持的显式转换。 C# 中的强制转换运算符或CTypeVisual Basic (中的转换方法(如果Option Strict) 需要执行转换)。

但是,如果源类型或目标类型都未定义两种类型之间的显式或缩小转换,并且 IConvertible 一种或两种类型的实现都不支持从源类型转换为目标类型, InvalidCastException 则会引发异常。

在大多数情况下,由于不支持转换,因此没有解决方法。

向下转换

正在向下转换,即尝试将基类型的实例转换为其派生类型之一。 在以下示例中,尝试将对象PersonWithID转换为Person对象失败。

using System;

public class Person
{
   String _name;

   public String Name
   {
      get { return _name; }
      set { _name = value; }
   }
}

public class PersonWithId : Person
{
   String _id;

   public string Id
   {
      get { return _id; }
      set { _id = value; }
   }
}

public class Example
{
   public static void Main()
   {
      Person p = new Person();
      p.Name = "John";
      try {
         PersonWithId pid = (PersonWithId) p;
         Console.WriteLine("Conversion succeeded.");
      }
      catch (InvalidCastException) {
         Console.WriteLine("Conversion failed.");
      }

      PersonWithId pid1 = new PersonWithId();
      pid1.Name = "John";
      pid1.Id = "246";
      Person p1 = pid1;
      try {
         PersonWithId pid1a = (PersonWithId) p1;
         Console.WriteLine("Conversion succeeded.");
      }
      catch (InvalidCastException) {
         Console.WriteLine("Conversion failed.");
      }

      Person p2 = null;
      try {
         PersonWithId pid2 = (PersonWithId) p2;
         Console.WriteLine("Conversion succeeded.");
      }
      catch (InvalidCastException) {
         Console.WriteLine("Conversion failed.");
      }
   }
}
// The example displays the following output:
//       Conversion failed.
//       Conversion succeeded.
//       Conversion succeeded.
open System

type Person() =
    member val Name = String.Empty with get, set

type PersonWithId() =
    inherit Person()
    member val Id = String.Empty with get, set


let p = Person()
p.Name <- "John"
try
    let pid = p :?> PersonWithId
    printfn "Conversion succeeded."
with :? InvalidCastException ->
    printfn "Conversion failed."

let pid1 = PersonWithId()
pid1.Name <- "John"
pid1.Id <- "246"
let p1: Person = pid1
try
    let pid1a = p1 :?> PersonWithId
    printfn "Conversion succeeded."
with :? InvalidCastException ->
    printfn "Conversion failed."

// The example displays the following output:
//       Conversion failed.
//       Conversion succeeded.
Public Class Person
   Dim _name As String
   
   Public Property Name As String
      Get
         Return _name
      End Get
      Set
         _name = value
      End Set
   End Property
End Class

Public Class PersonWithID : Inherits Person
   Dim _id As String
   
   Public Property Id As String
      Get
         Return _id
      End Get
      Set
         _id = value
      End Set
   End Property
End Class

Module Example
   Public Sub Main()
      Dim p As New Person()
      p.Name = "John"
      Try
         Dim pid As PersonWithId = CType(p, PersonWithId)
         Console.WriteLine("Conversion succeeded.")
      Catch e As InvalidCastException
         Console.WriteLine("Conversion failed.")
      End Try 
      
      Dim pid1 As New PersonWithId()
      pid1.Name = "John"
      pid1.Id = "246"
      Dim p1 As Person = pid1
      
      Try   
         Dim pid1a As PersonWithId = CType(p1, PersonWithId)
         Console.WriteLine("Conversion succeeded.")
      Catch e As InvalidCastException
         Console.WriteLine("Conversion failed.")
      End Try 
      
      Dim p2 As Person = Nothing
      Try   
         Dim pid2 As PersonWithId = CType(p2, PersonWithId)
         Console.WriteLine("Conversion succeeded.")
      Catch e As InvalidCastException
         Console.WriteLine("Conversion failed.")
      End Try 
   End Sub
End Module
' The example displays the following output:
'       Conversion failed.
'       Conversion succeeded.
'       Conversion succeeded.

如本示例所示,仅当Person对象由对象从PersonWithId对象向上转换或Person对象为null对象时,Person下播才会成功。

从接口对象转换

您正尝试将接口对象转换为实现该接口的类型,但目标类型与最初派生接口对象的类型的类型或基类不同。 以下示例尝试将对象转换为IFormatProvider对象DateTimeFormatInfo时引发InvalidCastException异常。 转换失败,因为虽然 DateTimeFormatInfo 类实现 IFormatProvider 接口,但 DateTimeFormatInfo 对象与从中派生接口对象的类无关 CultureInfo

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      var culture = CultureInfo.InvariantCulture;
      IFormatProvider provider = culture;

      DateTimeFormatInfo dt = (DateTimeFormatInfo) provider;
   }
}
// The example displays the following output:
//    Unhandled Exception: System.InvalidCastException:
//       Unable to cast object of type //System.Globalization.CultureInfo// to
//           type //System.Globalization.DateTimeFormatInfo//.
//       at Example.Main()
open System
open System.Globalization

let culture = CultureInfo.InvariantCulture
let provider: IFormatProvider = culture

let dt = provider :?> DateTimeFormatInfo

// The example displays the following output:
//    Unhandled Exception: System.InvalidCastException:
//       Unable to cast object of type //System.Globalization.CultureInfo// to
//           type //System.Globalization.DateTimeFormatInfo//.
//       at Example.main()
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim culture As CultureInfo = CultureInfo.InvariantCulture
      Dim provider As IFormatProvider = culture
      
      Dim dt As DateTimeFormatInfo = CType(provider, DateTimeFormatInfo)
   End Sub
End Module
' The example displays the following output:
'    Unhandled Exception: System.InvalidCastException: 
'       Unable to cast object of type 'System.Globalization.CultureInfo' to 
'           type 'System.Globalization.DateTimeFormatInfo'.
'       at Example.Main()

如异常消息所示,仅当接口对象转换回原始类型的实例时,转换才会成功,在本例中为 CultureInfo。 如果接口对象转换为原始类型的基类型的实例,转换也会成功。

字符串转换

尝试使用 C# 中的强制转换运算符将值或对象转换为其字符串表示形式。 在以下示例中,尝试将值强制转换为 Char 字符串,尝试将整数强制转换为字符串会引发 InvalidCastException 异常。

using System;

public class Example
{
   public static void Main()
   {
      object value = 12;
      // Cast throws an InvalidCastException exception.
      string s = (string) value;
   }
}
let value: obj = 12
// Cast throws an InvalidCastException exception.
let s = value :?> string

备注

使用 Visual Basic CStr 运算符将基元类型的值转换为字符串成功。 该操作不会引发 InvalidCastException 异常。

若要成功将任何类型的实例转换为其字符串表示形式,请调用其 ToString 方法,如以下示例所示。 该方法 ToString 始终存在,因为 ToString 该方法由 Object 类定义,因此由所有托管类型继承或重写。

using System;

public class Example
{
   public static void Main()
   {
      object value = 12;
      string s = value.ToString();
      Console.WriteLine(s);
   }
}
// The example displays the following output:
//      12
let value: obj = 12
let s = value.ToString()
printfn $"{s}"
// The example displays the following output:
//      12

Visual Basic 6.0 迁移

你正在升级一个 Visual Basic 6.0 应用程序,并在用户控件中调用自定义事件以Visual Basic .NET,并引发一个InvalidCastException异常,并显示消息“指定的强制转换无效”。 若要消除此异常,请更改表单中的代码行 (,例如 Form1)

Call UserControl11_MyCustomEvent(UserControl11, New UserControl1.MyCustomEventEventArgs(5))

并将其替换为以下代码行:

Call UserControl11_MyCustomEvent(UserControl11(0), New UserControl1.MyCustomEventEventArgs(5))

构造函数

InvalidCastException()

初始化 InvalidCastException 类的新实例。

InvalidCastException(SerializationInfo, StreamingContext)

用序列化数据初始化 InvalidCastException 类的新实例。

InvalidCastException(String)

用指定的错误消息初始化 InvalidCastException 类的新实例。

InvalidCastException(String, Exception)

使用指定的错误消息和对作为此异常原因的内部异常的引用来初始化 InvalidCastException 类的新实例。

InvalidCastException(String, Int32)

使用指定的消息和错误代码初始化 InvalidCastException 类的新实例。

属性

Data

获取键/值对的集合,这些键/值对提供有关该异常的其他用户定义信息。

(继承自 Exception)
HelpLink

获取或设置指向与此异常关联的帮助文件链接。

(继承自 Exception)
HResult

获取或设置 HRESULT(一个分配给特定异常的编码数字值)。

(继承自 Exception)
InnerException

获取导致当前异常的 Exception 实例。

(继承自 Exception)
Message

获取描述当前异常的消息。

(继承自 Exception)
Source

获取或设置导致错误的应用程序或对象的名称。

(继承自 Exception)
StackTrace

获取调用堆栈上的即时框架字符串表示形式。

(继承自 Exception)
TargetSite

获取引发当前异常的方法。

(继承自 Exception)

方法

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
GetBaseException()

当在派生类中重写时,返回 Exception,它是一个或多个并发的异常的根本原因。

(继承自 Exception)
GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetObjectData(SerializationInfo, StreamingContext)

当在派生类中重写时,用关于异常的信息设置 SerializationInfo

(继承自 Exception)
GetType()

获取当前实例的运行时类型。

(继承自 Exception)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
ToString()

创建并返回当前异常的字符串表示形式。

(继承自 Exception)

事件

SerializeObjectState
已过时。

当异常被序列化用来创建包含有关该异常的徐列出数据的异常状态对象时会出现该问题。

(继承自 Exception)

适用于

另请参阅