Közvetlen öntés vs „mint” operátor?

szavazat
565

Tekintsük a következő kódot:

void Handler(object o, EventArgs e)
{
   // I swear o is a string
   string s = (string)o; // 1
   //-OR-
   string s = o as string; // 2
   // -OR-
   string s = o.ToString(); // 3
}

Mi a különbség a három öntvény (oké, a 3. egy nem casting, de kapsz a szándék). Melyiket kell előnyben?

A kérdést 25/09/2008 11:09
a forrás felhasználó
Más nyelveken...                            


17 válasz

szavazat
6

„Mint” alapul „van”, ami olyan kulcsszó, amely ellenőrzi a futás, ha az objektum polimorphycally kompatibilis (alapvetően, ha a leadott lehet), és visszaadja null, ha az ellenőrzés sikertelen.

Ez a két ekvivalens:

Használata „mint”:

string s = o as string;

Segítségével „jelentése”:

if(o is string) 
    s = o;
else
    s = null;

Éppen ellenkezőleg, a c-stílusú öntött készül is a futás, de kivételt dob, ha a leadott nem lehet.

Csak, hogy adjunk egy fontos tényt:

Az „a” kulcsszó csak akkor működik, típusai. Nem lehet csinálni:

// I swear i is an int
int number = i as int;

Ezekben az esetekben meg kell használni casting.

Válaszolt 25/09/2008 11:15
a forrás felhasználó

szavazat
674

string s = (string)o; // 1

Dob InvalidCastException ha onem string. Ellenkező esetben rendeli oa s, akkor is, ha ovan null.

string s = o as string; // 2

Hozzárendeli nullaz s, ha onem string, vagy ha ovan null. Emiatt nem tudja használni a típusú érték (az üzemeltető soha nem tér vissza nullebben az esetben). Ellenkező esetben rendeli oa s.

string s = o.ToString(); // 3

Okoz NullReferenceException ha ovan null. Hozzárendeli bármi o.ToString()visszatér s, nem számít, hogy milyen típusú oaz.


Az 1 a legtöbb konverziót - ez egyszerű és egyértelmű. Én inkább szinte soha nem használja 2 óta, ha valami nem a megfelelő típusú, általában elvárják kivétel fordul elő. Én csak láttam ennek szükségességét visszatérő null típusú funkcionalitás rosszul tervezett könyvtárak használó hibakódok (pl visszatérő null = hiba, ahelyett, hogy a kivételek).

3 nem öntött, és csak egy metódusmeghívást. Használd, amikor szükség van a karakteres ábrázolása nem string objektumot.

Válaszolt 25/09/2008 11:16
a forrás felhasználó

szavazat
26

Ez tényleg attól függ, hogy tudja, ha oegy karakterlánc, és mit szeretne csinálni vele. Ha megjegyzése azt jelenti, hogy onagyon-nagyon egy string, én inkább az egyenes (string)oöntött - nem valószínű, hogy sikerül.

A legnagyobb előnye az egyenes öntött, hogy ha ez nem sikerül, akkor kap egy InvalidCastException , amely megmondja, hogy nagyjából mit rontottam el.

Az asüzemeltető, ha onem egy húr, sbeállítása null, ami praktikus, ha nem biztos, és szeretne teszt s:

string s = o as string;
if ( s == null )
{
    // well that's not good!
    gotoPlanB();
}

Azonban, ha nem végez, hogy a tesztet, akkor használja sújabb, és olyan NullReferenceException dobott. Ezek általában több közös és egy csomó nehezebb lenyomozni, ha azok történetesen ki a vad, mint szinte minden vonal dereferences változó, és dobja egyet. Másrészről, ha akarsz átküldeni az érték típusú (primitív vagy struktúrákat, mint DateTime ), akkor használja az egyenes leadott - az asnem fog működni.

Abban a speciális esetben, átkerül egy húr, minden objektumnak ToString, ezért a harmadik módszer lehet baj, ha onem nulla, és úgy gondolja, a ToStringmódszer lehet csinálni, amit akar.

Válaszolt 25/09/2008 11:16
a forrás felhasználó

szavazat
4

„(String) o” ​​fog eredményezni InvalidCastException mivel nincs közvetlen öntött.

„O string” eredményez s hogy egy null referencia, hanem kivétel dobálnak.

„O.ToString ()” nem öntött semmiféle per-se, ez egy módszer, ami által megvalósított tárgy, így egy ilyen vagy olyan módon, a minden osztályban .net, hogy „csinál valamit” a példány az osztály úgy hívják, és visszaad egy húr.

Ne felejtsük el, hogy a konvertálás húr, ott is Convert.ToString (sometype instanceOfThatType) ha sometype egyik egy sor típus lényegében a keretek alaptípusokat.

Válaszolt 25/09/2008 11:17
a forrás felhasználó

szavazat
276
  1. Akkor használja, ha valami kell feltétlenül lennie a másik dolog.
  2. Akkor használja, ha valami lehet a másik dolog.
  3. Használni, ha nem érdekel, mi ez, de csak azt, hogy a rendelkezésre álló karakteres ábrázolása.
Válaszolt 25/09/2008 11:31
a forrás felhasználó

szavazat
5

2 hasznos az öntéshez származtatott típusú.

Tegyük fel, hogy egy egy állat:

b = a as Badger;
c = a as Cow;

if (b != null)
   b.EatSnails();
else if (c != null)
   c.EatGrass();

kap egy táplált minimális vet.

Válaszolt 25/09/2008 11:31
a forrás felhasználó

szavazat
8

Ha már tudja, hogy milyen típusú akkor leadott, használjon C-style cast:

var o = (string) iKnowThisIsAString; 

Fontos, hogy csak egy C-stílusú öntött tud végrehajtani explicit típuskényszerítő.

Ha nem tudja, hogy ez a kívánt típusú és fogsz használni, ha használja a kulcsszó:

var s = o as string;
if (s != null) return s.Replace("_","-");

//or for early return:
if (s==null) return;

Vegye figyelembe, hogy mivel nem hívja bármilyen típusú átalakítás szereplők. Ez csak akkor lehet nulla, ha az objektum nem nulla és natívan a megadott típusú.

Használja toString (), hogy egy ember által olvasható szövegként bármilyen tárgy, akkor is, ha nem öntött a húr.

Válaszolt 25/09/2008 11:41
a forrás felhasználó

szavazat
3
string s = o as string; // 2

Az előnyös, hiszen így nem a teljesítmény büntetést kettős casting.

Válaszolt 25/09/2008 12:05
a forrás felhasználó

szavazat
7

Az a kulcsszó jó asp.net, ha használja a FindControl módszer.

Hyperlink link = this.FindControl("linkid") as Hyperlink;
if (link != null)
{
     ...
}

Ez azt jelenti, hogy működik a típusú változót, hanem majd, hogy aztán vesd el object, mint ahogy azt a közvetlen szereplők:

object linkObj = this.FindControl("linkid");
if (link != null)
{
     Hyperlink link = (Hyperlink)linkObj;
}

Ez nem egy nagy dolog, de takarít sornyi kódot és változó hozzárendelése, plusz ez olvashatóbb

Válaszolt 25/09/2008 12:17
a forrás felhasználó

szavazat
3

A kísérletek szerint futását az oldalon: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as

(Ez az oldal némi „illegális hivatkozó” hibák jelennek meg néha, úgyhogy csak frissíteni, ha igen)

Következtetés, a „mint” operátor általában gyorsabb, mint egy öntött. Néha sok-szor gyorsabb, néha csak alig gyorsabb.

Azt peronsonally dolog „mint” is olvashatóbb.

Tehát, mivel ez gyorsabb és „biztonságosabb” (szokás dobás kivételével), és esetleg könnyebben olvasható, azt javasoljuk a „mint” egész idő alatt.

Válaszolt 15/08/2010 19:36
a forrás felhasználó

szavazat
0

Amikor megpróbál a karakteres ábrázolása semmit (bármilyen típusú), amely potenciálisan null, én inkább a lenti kódsort. Ez a kompakt, meghívja a toString (), és helyesen kezeli nullákat. Ha o null, s tartalmazni fogja String.Empty.

String s = String.Concat(o);
Válaszolt 23/06/2012 02:31
a forrás felhasználó

szavazat
3

Minden adott válaszok jók, ha én is hozzá valamit: Ha közvetlenül használni húr módszerek és tulajdonságai (pl ToLower) nem írhat:

(string)o.ToLower(); // won't compile

akkor csak írd be:

((string)o).ToLower();

de meg tudná írni helyette:

(o as string).ToLower();

Az asopció olvashatóbb (legalábbis véleményem szerint).

Válaszolt 03/04/2014 15:28
a forrás felhasználó

szavazat
0

Mivel senki sem említette, a legközelebb a instanceof Java kulcsszó a következő:

obj.GetType().IsInstanceOfType(otherObj)
Válaszolt 13/10/2015 20:21
a forrás felhasználó

szavazat
2

Úgy tűnik, a kettő fogalmilag különbözik.

közvetlen Casting

Típus nem kell szigorúan összefügg. Jön minden típusú ízeket.

  • Egyedi implicit / explicit casting: Általában egy új objektumot hozunk létre.
  • Érték Típus Implicit: Másolás információk elvesztése nélkül.
  • Érték Típus Explicit: Copy és információk elveszhetnek.
  • IS-A kapcsolat: Change referencia típus, különben dob kivételt.
  • Ugyanolyan típusú: „Casting felesleges”.

Olyan, mintha a tárgy fog alakítani valami mást.

AS operátor

Típusok közvetlen kapcsolatot. Mint a:

  • Referencia típusok: IS-A kapcsolat objektumok mindig ugyanaz, csak a referencia-változásokat.
  • Érték típusai: Copy boksz és nullképes típusok.

Olyan, mintha az Ön fogja kezelni az objektumot egy másik utat.

Minták és IL

    class TypeA
    {
        public int value;
    }

    class TypeB
    {
        public int number;

        public static explicit operator TypeB(TypeA v)
        {
            return new TypeB() { number = v.value };
        }
    }

    class TypeC : TypeB { }
    interface IFoo { }
    class TypeD : TypeA, IFoo { }

    void Run()
    {
        TypeA customTypeA = new TypeD() { value = 10 };
        long longValue = long.MaxValue;
        int intValue = int.MaxValue;

        // Casting 
        TypeB typeB = (TypeB)customTypeA; // custom explicit casting -- IL:  call class ConsoleApp1.Program/TypeB ConsoleApp1.Program/TypeB::op_Explicit(class ConsoleApp1.Program/TypeA)
        IFoo foo = (IFoo)customTypeA; // is-a reference -- IL: castclass  ConsoleApp1.Program/IFoo

        int loseValue = (int)longValue; // explicit -- IL: conv.i4
        long dontLose = intValue; // implict -- IL: conv.i8

        // AS 
        int? wraps = intValue as int?; // nullable wrapper -- IL:  call instance void valuetype [System.Runtime]System.Nullable`1<int32>::.ctor(!0)
        object o1 = intValue as object; // box -- IL: box [System.Runtime]System.Int32
        TypeD d1 = customTypeA as TypeD; // reference conversion -- IL: isinst ConsoleApp1.Program/TypeD
        IFoo f1 = customTypeA as IFoo; // reference conversion -- IL: isinst ConsoleApp1.Program/IFoo

        //TypeC d = customTypeA as TypeC; // wouldn't compile
    }
Válaszolt 25/09/2016 04:47
a forrás felhasználó

szavazat
0

A közvetlen öntött string s = (string) o;ha a logikai összefüggésben az alkalmazás stringaz egyetlen érvényes típus. Ezzel a megközelítéssel, kapsz InvalidCastExceptionés elvének végrehajtására Fail gyors . A logika védve lesz átadva az érvénytelen típus további vagy kap NullReferenceException ha használt asoperátor.

Ha a logika számít, több különböző típusú öntött string s = o as string;és ellenőrizze azt null, vagy használja isoperátor.

Új hűvös vonás jelent meg a C # 7.0 egyszerűsítése öntött és ellenőrizze a Mintaegyezés :

if(o is string s)
{
  // Use string variable s
}

or

switch (o)
{
  case int i:
     // Use int variable i
     break;
  case string s:
     // Use string variable s
     break;
 }
Válaszolt 03/08/2017 07:34
a forrás felhasználó

szavazat
0

A következő két forma típusú konverzió (öntés) támogatott C #:

|

(Önéletrajz

• Alakítsa statikus típusú v c az adott kifejezést

• Csak akkor lehetséges, ha a dinamikus típusú v c, vagy egy altípusát c

• Ha nem, InvalidCastException dobott

|

v as C

• A nem-halálos variáns a (c) v

• Így átalakítani a statikus típus v c az adott kifejezést

• NULL, ha a dinamikus típusú v nem c, vagy egy altípusát c

Válaszolt 27/05/2018 13:17
a forrás felhasználó

szavazat
1

Szeretném felhívni magára a figyelmet, hogy a következő sajátosságait a mint operátor:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as

Megjegyezzük, hogy az operátor végzi a hivatkozás kizárólag konverziók nullképes konverziók és a boksz konverziót. A mint üzemeltető nem tudja végrehajtani más konverziót, mint a felhasználó által definiált konverzió, ami ehelyett alkalmazásával végezhető öntött kifejezéseket.

Válaszolt 17/10/2018 12:11
a forrás felhasználó

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