Støping: (NewType) mot objektet som NewType

stemmer
79

Mulig Duplicate:
Casting vs bruker 'som' søkeordet i CLR

Hva er egentlig forskjellen mellom disse to kast?

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

Normalt bør de begge være eksplisitte kaster til den angitte typen?

Publisert på 05/08/2008 klokken 15:42
kilden bruker
På andre språk...                            


13 svar

stemmer
83

Den tidligere vil kaste et unntak hvis kildetype ikke kan avgis til målet type. Den sistnevnte vil resultere i sc2 være en null referanse, men ikke noe unntak.

[Redigere]

Min opprinnelige Svaret er absolutt den mest uttalt forskjell, men som Eric Lippert påpeker , er det ikke den eneste. Andre forskjeller inkluderer:

  • Du kan ikke bruke 'som' operatør å kaste til en type som ikke godtar 'null' som en verdi
  • Du kan ikke bruke 'som' å konvertere ting, som tallene til en annen representasjon (float til int, for eksempel).

Og til slutt, ved hjelp av 'som' vs. kastet operatør, er du også si "Jeg er ikke sikker på om dette vil lykkes."

Svarte 05/08/2008 kl. 15:44
kilden bruker

stemmer
27

Vær også oppmerksom på at du bare kan bruke som søkeord med en referansetype eller en kan ha nullverdier typen

dvs:

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

vil ikke kompilere

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

vil kompilere.

Svarte 05/08/2008 kl. 16:15
kilden bruker

stemmer
10

Typecasting å bruke "som" er selvfølgelig mye raskere når cast svikter, så det unngår bekostning av å kaste et unntak.

Men det er ikke raskere når cast lykkes. Grafen på http://www.codeproject.com/KB/cs/csharpcasts.aspx er misvisende fordi det ikke forklare hva det er å måle.

Poenget er:

  • Hvis du forventer cast å lykkes (dvs. en fiasko vil være eksepsjonell), bruker en støpt.

  • Hvis du ikke vet om det vil lykkes, bruk "som" operatør og teste resultatet for null.

Svarte 16/09/2008 kl. 19:21
kilden bruker

stemmer
5

En forskjell mellom de to metodene er at den første ((SomeClass) obj) kan forårsake en typeomformer for å bli kalt.

Svarte 07/11/2008 kl. 23:46
kilden bruker

stemmer
4

Vel det 'som' operatør "hjelper" deg begrave problemet langt lavere fordi når det er gitt en inkompatibel eksempel det vil returnere null, kanskje du vil gi denne til en metode som vil gi det til en annen, og så videre og til slutt' ll få en NullReferenceException som vil gjøre debugging hardere.

Ikke misbruke den. Den direkte kastet føreren er bedre i 99% av tilfellene.

Svarte 28/10/2010 kl. 09:21
kilden bruker

stemmer
4

Her er en god måte å huske prosessen som hver av dem følger som jeg bruker når jeg prøver å bestemme hvilken som er bedre for min situasjon.

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

og den neste skal være enkelt å gjette hva det gjør

DateTime i = value as DateTime;

i det første tilfellet dersom verdien ikke kan støpes enn et unntak i det andre tilfellet dersom verdien ikke kan støpes, i er satt til null.

Så i det første tilfellet en hard stopp gjøres dersom støpt svikter i andre kastet en myk stopp er gjort og du kan støte på en NullReferenceException senere.

Svarte 05/08/2008 kl. 17:46
kilden bruker

stemmer
3

Å utvide Rytmis kommentar , kan du ikke bruke den som søkeord for structs (verdityper), som de har ingen nullverdi.

Svarte 07/09/2008 kl. 08:08
kilden bruker

stemmer
2

Alt dette gjelder referansetyper, verdityper kan ikke bruke assøkeord som de ikke kan være null.

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


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

Skuespillerne syntaks er raskere, men bare når vellykket, er det mye tregere til å mislykkes.

Beste praksis er å bruke asnår du ikke vet hvilken type:

//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
}

Men hvis du er helt sikker på at someObjecter et eksempel på SomeClassbruk deretter kastet.

I Net 2 eller høyere generika bety at du svært sjelden trenger å ha en un-skrev forekomst av en referanse klassen, slik at sistnevnte blir sjeldnere brukt.

Svarte 18/09/2008 kl. 11:10
kilden bruker

stemmer
1

Og for ordens skyld, har Eric Lippert et blogginnlegg om forskjellen og noen ting.

Svarte 09/10/2009 kl. 00:04
kilden bruker

stemmer
1

For de av dere med VB.NET erfaring, (type) er det samme som DirectCast og "som type" er det samme som TryCast.

Svarte 16/09/2008 kl. 21:55
kilden bruker

stemmer
1

Det er som forskjellen mellom Analyser og TryParse. Du bruker TryParse når du forventer det kan mislykkes, men når du har sterk forsikring om den ikke vil svikte deg bruke Parse.

Svarte 08/08/2008 kl. 12:00
kilden bruker

stemmer
1

De vil kaste forskjellige unntak.
(): NullReferenceException
som: InvalidCastException
som kan bidra for debugging.

"AS" søkeord forsøk på å kaste gjenstanden og hvis kastet svikter, null returneres lydløst. Den () kastet operatør vil kaste et unntak umiddelbart hvis cast svikter.

"Bruk bare C # 'som' søkeord der du forventer kastet til å mislykkes i en ikke-eksepsjonell sak. Hvis du regner med en støpt for å lykkes og er forberedt på å motta et objekt som ville mislykkes, bør du bruke () kastet operatør slik at en hensiktsmessig og nyttig unntak."

For kode eksempler og en nærmere forklaring: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

Svarte 05/08/2008 kl. 15:49
kilden bruker

stemmer
1

Parentes kastet kaster et unntak hvis støpt forsøket mislykkes. Den "som" støpt returnerer null hvis støpt forsøket mislykkes.

Svarte 05/08/2008 kl. 15:45
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more