이 문서는 이 API에 대한 참조 설명서를 보충하는 추가 설명을 제공합니다.
.NET은 파생 형식에서 기본 형식으로의 자동 변환과, 그리고 원래의 파생 형식으로 다시 변환을 지원합니다. 또한, 인터페이스를 제공하는 형식에서 인터페이스 개체로의 변환 및 그 반대 방향으로의 자동 변환도 지원합니다. 또한 사용자 지정 변환을 지원하는 다양한 메커니즘을 포함합니다. 자세한 내용은 .NET의 형식 변환을 참조하세요.
InvalidCastException 한 형식의 인스턴스를 다른 형식으로 변환할 수 없는 경우 예외가 throw됩니다. 예를 들어 Char 값을 DateTime 값으로 변환하려고 시도하면 InvalidCastException 예외가 발생합니다. 한 형식을 다른 형식으로 변환할 수 있는 경우에도, 원본 형식의 값이 대상 형식의 범위를 초과할 때 발생하는 예외와는 다릅니다 OverflowException.
InvalidCastException 예외는 개발자 오류로 인해 발생하며 블록에서 try/catch
처리해서는 안 됩니다. 대신 예외의 원인을 제거해야 합니다.
시스템에서 지원하는 변환에 대한 자세한 내용은 클래스를 Convert 참조하세요. 대상 형식이 원본 형식 값을 저장할 수 있지만 특정 원본 값을 저장할 만큼 크지 않을 때 발생하는 오류는 예외를 OverflowException 참조하세요.
비고
대부분의 경우 언어 컴파일러는 원본 형식과 대상 형식 간에 변환이 없음을 감지하고 컴파일러 오류를 발생합니다.
변환 시도가 예외 InvalidCastException를 발생시키는 조건 중 일부는 다음 섹션에서 설명합니다.
명시적 참조 변환에 성공하려면 원본 값이어야 null
합니다. 또는 소스 인수에서 참조하는 개체 형식을 암시적 참조 변환을 통해 대상 형식으로 변환할 수 있어야 합니다.
다음 중간 언어(IL) 명령은 InvalidCastException 예외를 throw합니다.
castclass
refanyval
unbox
InvalidCastException 는 값이 0x80004002 HRESULT COR_E_INVALIDCAST
를 사용합니다.
InvalidCastException인스턴스의 초기 속성 값 목록은 InvalidCastException 생성자를 참조하세요.
기본 형식 및 IConvertible
특정 변환을 지원하지 않는 기본 형식의 IConvertible 구현을 직접 또는 간접적으로 호출합니다. 예를 들어, Boolean 값을 Char로 변환하거나, DateTime 값을 Int32로 변환하려고 하면 InvalidCastException 예외가 발생합니다. 다음 예제에서는 Boolean.IConvertible.ToChar 값을 Convert.ToChar(Boolean)로 변환하기 위해 Boolean 메서드와 Char 메서드를 모두 호출합니다. 두 경우 모두 메서드 호출이 InvalidCastException 예외를 발생시킵니다.
using System;
public class IConvertibleEx
{
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 Example2
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#의 캐스팅 연산자 또는 CType
Visual Basic의 변환 메서드(있는 경우 Option Strict
)가 필요합니다.
그러나 원본 형식이나 대상 형식이 두 형식 간의 명시적 또는 축소 변환을 정의하지 않고 하나 또는 두 형식 IConvertible 의 구현이 원본 형식에서 대상 형식 InvalidCastException 으로의 변환을 지원하지 않는 경우 예외가 throw됩니다.
대부분의 경우 변환이 지원되지 않으므로 해결 방법이 없습니다.
다운캐스팅
다운캐스트는 기본 형식의 인스턴스를 파생 형식 중 하나로 변환하려고 하는 경우를 말합니다. 다음 예제에서는 Person
개체를 PersonWithID
개체로 변환하려고 하면 실패합니다.
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 Example1
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
개체로 업캐스트되는 과정에서 생성된 경우, 또는 Person
개체가 null
인 경우에만 성공합니다.
인터페이스 객체에서 변환
인터페이스 개체를 해당 인터페이스를 구현하는 형식으로 변환하려고 하지만 대상 형식은 인터페이스 개체가 원래 파생된 형식의 동일한 형식 또는 기본 클래스가 아닙니다. 다음 예제에서는 InvalidCastException 개체를 IFormatProvider 개체로 변환하려고 할 때 DateTimeFormatInfo 예외를 던집니다. 변환이 실패하는 이유는 DateTimeFormatInfo 클래스가 IFormatProvider 인터페이스를 구현했지만, DateTimeFormatInfo 개체가 인터페이스 개체가 파생된 CultureInfo 클래스와 관련이 없기 때문입니다.
using System;
using System.Globalization;
public class InterfaceEx
{
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 Example3
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 예외를 발생시킵니다.
public class StringEx
{
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 ToStringEx2
{
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 .NET으로 호출하여 Visual Basic 6.0 애플리케이션을 업그레이드하고 있으며 InvalidCastException " "지정된 캐스트가 유효하지 않습니다."라는 메시지와 함께 예외가 throw됩니다. 이 예외를 제거하려면 양식의 코드 줄을 변경합니다(예: Form1
).
Call UserControl11_MyCustomEvent(UserControl11, New UserControl1.MyCustomEventEventArgs(5))
다음 코드 줄로 바꿉다.
Call UserControl11_MyCustomEvent(UserControl11(0), New UserControl1.MyCustomEventEventArgs(5))
.NET