Vra

  

Moontlike Dubbele:
   Casting vs behulp van die "as 'navraag in die CLR

Wat is eintlik die verskil tussen hierdie twee gooi?

SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;

Gewoonlik, moet hulle altwee wees eksplisiete gooi om die gespesifiseerde tipe?

Was dit nuttig?

Oplossing

Die voormalige sal 'n uitsondering te gooi as die tipe bron nie kan gooi na die teiken tipe. Laasgenoemde sal lei tot sc2 'n nul verwysing, maar geen uitsondering nie.

[wysig]

My oorspronklike antwoord is beslis die mees uitgespreek verskil, maar as Eric Lippert wys daarop , dit is nie die enigste een. Ander verskille sluit in:

  • Jy kan nie die 'as' operateur gebruik om te gooi om 'n tipe wat nie 'null 'n waarde
  • aanvaar
  • Jy kan nie gebruik 'as' to skakel dinge, soos getalle na 'n ander voorstelling (float na int, byvoorbeeld).

En laastens, die gebruik van 'as' teen die cast operateur, jy ook sê: "Ek is nie seker of dit sal slaag."

Ander wenke

Let ook daarop dat u net kan gebruik om die as navraag met 'n verwysing tipe of 'n waarvoor geen nul mag tipe

naamlik:

double d = 5.34;
int i = d as int;

sal nie saam te stel

double d = 5.34;
int i = (int)d;

sal stel.

typecasting met behulp van "as" is natuurlik baie vinniger as die cast versuim, as dit die koste van die gooi van 'n uitsondering vermy.

Dit is egter nie vinniger as die rolverdeling slaag. Die grafiek op http://www.codeproject.com/KB/cs/csharpcasts.aspx is misleidend omdat dit nie verduidelik wat dit meet.

Die bottom line is:

  • As jy verwag dat die rolverdeling te slaag (dit wil sê 'n mislukking sou uitsonderlike wees), gebruik 'n cast.

  • As jy weet nie of dit sal slaag, gebruik die "as" operateur en die toets van die resultaat for null.

'n verskil tussen die twee benaderings is dat die die eerste ((SomeClass) obj) kan 'n tipe converter genoem te word nie.

Hier is 'n goeie manier om die proses wat elkeen van hulle te volg wat ek gebruik wanneer ek probeer om te besluit wat is beter vir my omstandighede onthou.

DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);

en die volgende moet maklik wees om te raai wat dit doen

DateTime i = value as DateTime;

In die eerste geval indien die waarde nie kan gooi as 'n uitsondering is gegooi in die tweede geval indien die waarde nie kan gooi, is ek stel aan nul.

So in die eerste geval 'n harde stop gemaak as die cast versuim in die tweede cast 'n sagte stop gemaak en jy kan 'n NullReferenceException later op teëkom.

Wel die 'as' operateur "help" jy begrawe jou probleem manier laer want as dit verskaf 'n onversoenbare byvoorbeeld dit nul sal terugkeer, miskien sal jy slaag dat 'n metode wat sal slaag dit na 'n ander en so aan en uiteindelik sal jy 'n NullReferenceException wat jou debugging moeiliker sal maak nie.

Moenie misbruik dit. Die direkte cast operateur is beter in 99% van die gevalle.

Om uit te brei op Rytmis se kommentaar , kan jy nie gebruik die as navraag vir structs (waarde tipes), want hulle het geen null waarde.

Al hierdie geld vir tipe verwysing, kan tipes waarde die as navraag nie gebruik as hulle nie nul kan wees.

//if I know that SomeObject is an instance of SomeClass
SomeClass sc = (SomeClass) someObject;


//if SomeObject *might* be SomeClass
SomeClass sc2 = someObject as SomeClass;

Die rolverdeling sintaksis is vinniger, maar net vir suksesvolle, dit is veel stadiger te misluk.

Beste praktyk is om as gebruik wanneer jy nie die tipe leer ken:

//we need to know what someObject is
SomeClass sc;
SomeOtherClass soc;

//use as to find the right type
if( ( sc = someObject as SomeClass ) != null ) 
{
    //do something with sc
}
else if ( ( soc = someObject as SomeOtherClass ) != null ) 
{
    //do something with soc
}

Maar as jy absoluut seker dat someObject is 'n geval van SomeClass gebruik dan cast.

In Net 2 of hoër beteken generiese dat jy baie selde nodig het om 'n VN-getikte voorbeeld van 'n verwysing klas het, so laasgenoemde minder dikwels gebruik.

Die hakies cast gooi 'n uitsondering as die cast poging misluk. Die "as" cast terugkeer null as die cast poging misluk.

Hulle sal verskillende uitsonderings gooi.
(): NullReferenceException
as: InvalidCastException
Wat kan help om foute.

Die "as" navraag pogings om die voorwerp te gooi en as die cast versuim, nul is stil teruggekom. Die () cast operateur sal 'n uitsondering onmiddellik gooi as die cast versuim.

"Gebruik slegs die C #" as "navraag waar jy verwag dat die cast om te misluk in 'n nie-uitsonderlike geval. As jy is toe op 'n cast om suksesvol te wees en is nie gereed om enige voorwerp wat sou versuim ontvang, moet jy gebruik die () cast operateur sodat 'n geskikte en nuttige uitsondering is gegooi. "

Vir kode voorbeelde en 'n verdere verduideliking: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

Dit is soos die verskil tussen Parse en TryParse. Jy gebruik TryParse wanneer jy verwag dat dit kan misluk nie, maar wanneer jy 'n sterk sekerheid sal dit vir jou nooit Parse gebruik.

Vir dié van julle met VB.NET ervaring, (tipe) is dieselfde as DirectCast en "as tipe" is dieselfde as TryCast.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top