Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
.NET podporuje automatický převod odvozených typů na jejich základní typy a zpět na odvozený typ, stejně jako z typů, které představují rozhraní na objekty rozhraní a zpět. Zahrnuje také řadu nástrojů, které podporují vlastní převody. Další informace naleznete v tématu Převod typů v .NET.
Výjimka InvalidCastException je vyvolána v případě, že převod instance jednoho typu na jiný typ není podporován. Například pokus o převod hodnoty Char na hodnotu DateTime vyvolá výjimku InvalidCastException. Liší se od OverflowException výjimky, která se vyvolá, když je podporován převod jednoho typu na jiný, ale hodnota zdrojového typu je mimo rozsah cílového typu. Výjimka InvalidCastException je způsobená chybou vývojáře a neměla by být řešena v bloku try/catch. Místo toho by se měla odstranit příčina výjimky.
Informace o převodech podporovaných systémem naleznete ve Convert třídě. Pro chyby, ke kterým dochází, když cílový typ může ukládat hodnoty zdrojového typu, ale není dostatečně velký k uložení konkrétní zdrojové hodnoty, podívejte se na výjimku OverflowException.
Poznámka:
V mnoha případech kompilátor jazyka zjistí, že mezi zdrojovým typem a cílovým typem neexistuje žádný převod a vydává chybu kompilátoru.
Některé z podmínek, za kterých pokus o převod vyvolá InvalidCastException výjimku, jsou popsány v následujících částech.
Aby byl explicitní převod odkazu úspěšný, musí být nullzdrojová hodnota nebo typ objektu odkazovaný zdrojovým argumentem musí být převoditelný na cílový typ implicitním převodem odkazu.
Následující pokyny pro zprostředkující jazyk (IL) vyvolají InvalidCastException výjimku:
castclassrefanyvalunbox
InvalidCastException používá HODNOTU HRESULT COR_E_INVALIDCAST, která má hodnotu 0x80004002.
Seznam počátečních hodnot vlastností pro instanci InvalidCastExceptionnaleznete v konstruktoru InvalidCastException.
Primitivní typy a IConvertible
Přímo nebo nepřímo voláte implementaci primitivního typu IConvertible , která nepodporuje konkrétní převod. Například pokus o převod hodnoty Boolean na hodnotu Char nebo hodnoty DateTime na hodnotu Int32 vyvolá výjimku InvalidCastException. Následující příklad volá jak metodu Boolean.IConvertible.ToChar, tak metodu Convert.ToChar(Boolean) k převodu hodnoty Boolean na Char. V obou případech vyvolá volání InvalidCastException metody výjimku.
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.
Protože převod není podporovaný, neexistuje žádné alternativní řešení.
Metoda Convert.ChangeType
Volali jste metodu Convert.ChangeType pro převod objektu z jednoho typu na jiný, ale jeden nebo oba typy neimplementují IConvertible rozhraní.
Ve většině případů, protože převod není podporovaný, neexistuje žádné alternativní řešení. V některých případech je možným alternativním řešením ruční přiřazení hodnot vlastností ze zdrojového typu k podobným vlastnostem cílového typu.
Zúžení při převodech a implementace IConvertible
Zužující operátory definují explicitní převody podporované typem. K provedení převodu se vyžaduje operátor přetypování v jazyce C# nebo metoda převodu CType v jazyce Visual Basic (pokud Option Strict je zapnutá).
Pokud však zdrojový typ ani cílový typ nedefinuje explicitní nebo zužující převod mezi těmito dvěma typy a IConvertible implementace jednoho nebo obou typů nepodporuje převod ze zdrojového typu na cílový typ, InvalidCastException vyvolá se výjimka.
Ve většině případů, protože převod není podporovaný, neexistuje žádné alternativní řešení.
Konverze na nižší úroveň typů
Přetypováváte (downcasting), to znamená, že se pokoušíte převést instanci základního typu na jeden z jeho odvozených typů. V následujícím příkladu se pokus o převod objektu Person na objekt PersonWithID nezdaří.
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.
Jak ukazuje příklad, downcast uspěje pouze tehdy, když byl objekt Person vytvořen upcastem z objektu PersonWithId na objekt Person, nebo když je objekt Personnull.
Převod z objektu rozhraní
Pokoušíte se převést objekt rozhraní na typ, který implementuje toto rozhraní, ale cílový typ není stejný typ nebo základní třída typu, ze kterého byl objekt rozhraní původně odvozen. Následující příklad vyvolá InvalidCastException výjimku, když se pokusí převést IFormatProvider objekt na DateTimeFormatInfo objekt. Převod selže, protože ačkoli DateTimeFormatInfo třída implementuje IFormatProvider rozhraní, objekt nesouvisí s DateTimeFormatInfo třídou, CultureInfo ze které byl objekt rozhraní odvozen.
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()
Jak zpráva o výjimce označuje, převod by byl úspěšný pouze v případě, že je objekt rozhraní převeden zpět na instanci původního typu, v tomto případě .CultureInfo Převod by také byl úspěšný, pokud je objekt rozhraní převeden na instanci základního typu původního typu.
Převody řetězců
Pokoušíte se převést hodnotu nebo objekt na řetězcovou reprezentaci pomocí operátoru přetypování v jazyce C#. V následujícím příkladu se pokus o převedení Char hodnoty na řetězec i pokus o převedení celého čísla na řetězec vyvolá InvalidCastException výjimku.
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
Poznámka:
Pomocí operátoru jazyka Visual Basic CStr úspěšně převedete hodnotu primitivního typu na řetězec. Operace nevyvolá InvalidCastException výjimku.
Chcete-li úspěšně převést instanci libovolného typu na řetězcové vyjádření, zavolejte jeho ToString metodu, jak to dělá následující příklad. Metoda ToString je vždy přítomna, protože ToString metoda je definována Object třídou, a proto je buď zděděna nebo přepsána všemi spravovanými typy.
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
Migrace jazyka Visual Basic 6.0
Upgradujete aplikaci jazyka Visual Basic 6.0 s voláním vlastní události v uživatelském ovládacím prvku na Visual Basic .NET a je vyvolána výjimka se zprávou "Zadané přetypování není platné." Chcete-li tuto výjimku odstranit, změňte řádek kódu ve formuláři (například InvalidCastException)
Call UserControl11_MyCustomEvent(UserControl11, New UserControl1.MyCustomEventEventArgs(5))
a nahraďte ho následujícím řádkem kódu:
Call UserControl11_MyCustomEvent(UserControl11(0), New UserControl1.MyCustomEventEventArgs(5))