2009-07-23 13 views
64

Questo non è davvero un problema, tuttavia sono curioso. Quando salvi una stringa, diciamo una DataRow, viene lanciata su Object. Quando voglio usarlo, devo lanciare ToString. Per quanto ne so ci sono diversi modi di fare questo, in primo luogo èCasting vs Conversione di un oggetto in Stringa, quando l'oggetto è davvero una stringa

string name = (string)DataRowObject["name"]; //valid since I know it's a string 

e un altro è:

string name = DataRowObject["name"].ToString(); 

Sono interessato in quello che è la differenza tra i due? Il primo è più efficiente? (Questa è solo una speculazione, nella mia testa il metodo ToString() è implementato da un meccanismo di looping in cui solo il casting "potrebbe" essere più veloce, tuttavia questo è solo un "istinto" che ho).

C'è persino un modo più veloce/elegante di farlo?

Qualcuno può chiarire questo per me?

+3

So che hai menzionato che l'oggetto è una stringa, ma nel caso in cui non sei sicuro che l'oggetto restituito sia nullo, puoi anche eseguire il cast utilizzando "Convert.ToString (DataRowObject [" nome "]);" Questo ha l'ulteriore vantaggio di restituire una stringa vuota (string.empty) se l'oggetto è null, per evitare eventuali eccezioni di riferimento null. – n00b

risposta

47

I due sono destinati a diversi scopi . Il metodo ToString di qualsiasi oggetto deve restituire una stringa rappresentazione di tale oggetto. La trasmissione è molto diversa e la parola chiave 'as' esegue un cast condizionale, come è stato detto . La parola chiave 'as' in pratica dice "prendi un riferimento a di questo tipo per quell'oggetto se quell'oggetto è di questo tipo" mentre ToString dice "procurami una rappresentazione di stringa di quell'oggetto".Il risultato potrebbe essere lo stesso in alcuni casi, ma i due devono essere mai considerati intercambiabili perché, come ho detto, esistono per diversi scopi. Se il tuo intento è , devi sempre usare un cast, NON ToString.

da http://www.codeguru.com/forum/showthread.php?t=443873

vedi anche http://bytes.com/groups/net-c/225365-tostring-string-cast

+0

Quindi, se ho capito bene. .ToString restituirà sempre una stringa dell'oggetto. Mentre il casting fallirà se non può essere restituito come una stringa? – DaImTo

+1

@DaImTo: quando si esegue il cast di un oggetto dal tipo A al tipo B (se il casting) è successo, si avrà un nuovo oggetto, che è possibile ricondurre al tipo A. Il casting non cambia chi sono (il nucleo), ma cambia ciò che sarà visto come. La conversione, in casi comuni, è un biglietto di sola andata. Crea un nuovo oggetto (solo) rappresenta per il vecchio oggetto. Es: un oggetto studente st quando converti inString() sarà una stringa simile a uno studente: @ 1343; 43234. pensi di poterlo trasformare in uno studente che ha valore nel campo? – Andiana

+0

@Andiana Nel libro Esame Ref per C# si dice "Quando si creano i propri tipi, è possibile sovrascrivere ToString per restituire una rappresentazione di stringa dell'oggetto. Se necessario, è possibile creare un metodo Parse e TryParse che converta la stringa indietro All'oggetto originale è richiesta l'implementazione dell'interfaccia IFormattable, così che il tuo oggetto può essere usato dalla classe Convert. " Potresti spiegarlo alla luce di ciò che hai detto prima. Grazie –

27

Se si sa che è un String, quindi con tutti i mezzi gettarlo a un String. La trasmissione dell'oggetto sarà più veloce rispetto alla chiamata a un metodo virtuale.

Edit: Ecco i risultati di alcune analisi comparativa:

============ Casting vs. virtual method ============ 
cast 29.884 1.00 
tos 33.734 1.13 

ho usato Jon Skeet BenchmarkHelper come questo:

using System; 
using BenchmarkHelper; 

class Program 
{ 
    static void Main() 
    { 
     Object input = "Foo"; 
     String output = "Foo"; 

     var results 
      = TestSuite.Create("Casting vs. virtual method", input, output) 
      .Add(cast) 
      .Add(tos) 
      .RunTests() 
      .ScaleByBest(ScalingMode.VaryDuration); 

     results.Display(ResultColumns.NameAndDuration | ResultColumns.Score, 
       results.FindBest()); 
    } 

    static String cast(Object o) 
    { 
     return (String)o; 
    } 

    static String tos(Object o) 
    { 
     return o.ToString(); 
    } 
} 

Così sembra che casting è di fatto leggermente più veloce di chiamare ToString().

+1

@Andrew: l'hai messo a confronto? Potrebbe essere cambiato, ma l'ultima volta che l'ho confrontato ho scoperto che il metodo virtuale era in realtà più veloce. Non mi aspettavo che fosse, ma lo era. –

+0

@Jon - No, non l'ho fatto!Dovrò verificarlo per essere sicuro. –

+1

@ AndrewHare- Il collegamento di Jon porta a un 505 – TheGeekZn

16

Fondamentalmente nel tuo caso è meglio lasciare il cast del tipo perché .ToString() può nascondere bug. Ad esempio, lo schema del tuo database è cambiato e il nome non è più di tipo stringa ma con .ToString() il tuo codice funziona ancora. Quindi in questo caso è meglio usare il cast di tipo.

Ecco attuazione String.ToString() - niente di speciale =)

public override string ToString() 
{ 
    return this; 
} 
+5

+1 per la decompilazione di String.ToString() –

5

downcasting è un'operazione relativamente lenta dal CLR deve eseguire varie di funzionamento Tipo controlli. Tuttavia, in questo particolare scenario, il casting su string è più appropriato della chiamata a ToString() per coerenza (non è possibile chiamare ToInt32 su object, ma trasmetterlo a int) e manutenibilità.

+0

Potrebbe non essere lento come pensi - per favore vedi la mia risposta. –

2

In questo caso:

string name = DataRowObject["name"].ToString(); 

poiché è un string, ritengo che il metodo di un oggetto stringa ToString() è semplice:

return this; 

quindi IMHO non ci sono penalità per le prestazioni.

PS Sono un programmatore Java, quindi questo anwser è solo un'ipotesi.

+0

Penso che DataRowObject non abbia conoscenza dei tipi e memorizzi tutto come Oggetti, quindi non è sicuramente così semplice come restituirlo. –

+3

@martjin_himself benvenuti nel mondo di Object Orientation, permettetemi di presentarvi un nuovo amico: Polymorphism. – fortran

+0

@fortran ti dispiacerebbe elaborare? Sono consapevole che tutto è un oggetto e il polimorfismo ti consente di trattare una stringa come se fosse un oggetto, tuttavia ciò è irrilevante qui, a meno che mi manchi qualcosa? evviva –

1

ToString() non esegue un cast per impostazione predefinita. Il suo scopo è quello di restituire una stringa che rappresenta il tipo (ad esempio "System.Object").

Se si desidera evitare il casting, è possibile provare a pensare a un'implementazione fortemente tipizzata (utilizzando generici, ad esempio) ed evitare del tutto DataRowObject.

2

Per l'oggetto dati, suggerisco di utilizzare la parola chiave "as" come il seguente codice.

string name = DataRowObject["name"] as string; 

Controllare prima di utilizzare il valore.

if(name != null) 
{ 
    // statement for empty string or it has value 
} 
else 
{ 
    // statement for no data in this object.  
} 
+0

sarebbe una versione più tersa dello stesso: 'string name = (fila ["nome"] come stringa) ?? "default"; ' –

4

Voglio fare un altro commento

Se avete intenzione di utilizzare casting: string name = (stringa) DataRowObject [ "nome"] si otterrà un'eccezione: Impossibile eseguire il cast oggetto di digitare 'System.DBNull' per digitare 'System.String' nel caso in cui il record nella tabella del database abbia valore nullo.

In questo scenario è necessario utilizzare:. String name = DataRowObject ToString [ "nome"]() o

Devi controllare per valore nullo come

if(!string.IsNullOrEmpty(DataRowObject["name"].ToString())) 
{ 
string name = (string)DataRowObject["name"]; 
} 
else 
{ 
//i.e Write error to the log file 
string error = "The database table has a null value"; 

} 
0

so lei ha detto che l'Oggetto è una stringa, ma nel caso in cui temiate che l'oggetto restituito sia nullo, potete anche eseguire il cast usando "Convert.ToString (DataRowObject [" nome "]);" Questo ha l'ulteriore vantaggio di restituire una stringa vuota (string.empty) se l'oggetto è null, per evitare eventuali eccezioni di riferimento null (a meno che, ovviamente, non si voglia generare un'eccezione in questi casi).

+0

C'è un ulteriore vantaggio nell'usare" Convert.ToString "e cioè che è possibile passare un valore nullo senza che venga lanciata un'eccezione. [Link] (http://msdn.microsoft.com/en-us/library/astxcyeh.aspx) – Remy

Problemi correlati