web-dev-qa-db-fra.com

Casting vs Converting an object toString, when object really is a string

Ce n'est pas vraiment un problème, mais je suis curieux. Lorsque j'enregistre une chaîne dans, disons un DataRow, elle est convertie en Object. Quand je veux l'utiliser, je dois le lancer sur ToString. Pour autant que je sache, il existe plusieurs façons de procéder, la première

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

et un autre est:

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

Je m'intéresse à quelle est la différence entre les deux? Le premier est-il plus efficace? (Ce n'est qu'une spéculation, dans ma tête, la méthode ToString () est implémentée par un mécanisme de boucle où le lancer "pourrait" être plus rapide, mais ce n'est qu'un "sentiment d'intestin" que j'ai).

Existe-t-il même un moyen plus rapide/plus élégant de le faire?

Quelqu'un peut-il clarifier cela pour moi?

70
David Božjak

Les deux sont destinés à des fins différentes. La méthode ToString de tout objet est censée renvoyer une représentation sous forme de chaîne de cet objet. La diffusion est très différente, et la clé "as" Word effectue une conversion conditionnelle, comme cela a été dit. La clé "as" Word dit essentiellement "obtenez-moi une référence de ce type à cet objet si cet objet est de ce type" tandis que ToString dit "obtenez-moi une représentation sous forme de chaîne de cet objet". Le résultat peut être le même dans certains cas, mais les deux ne doivent jamais être considérés comme interchangeables car, comme je l'ai dit, ils existent à des fins différentes. Si votre intention est de lancer, vous devez toujours utiliser un casting, PAS ToString.

de http://www.codeguru.com/forum/showthread.php?t=44387

voir aussi http://bytes.com/groups/net-c/225365-tostring-string-cast

50
Adriaan Stander

Si vous savez qu'il s'agit d'un String, convertissez-le en un String. La conversion de votre objet sera plus rapide que l'appel d'une méthode virtuelle.

Edit: Voici les résultats de quelques analyses comparatives:

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

J'ai utilisé le BenchmarkHelper de Jon Skeet comme ceci:

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();
    }
}

Il apparaît donc que le cast est en fait légèrement plus rapide que d'appeler ToString().

30
Andrew Hare

Fondamentalement, dans votre cas, il est préférable de laisser le type cast car .ToString () peut masquer les bogues. Par exemple, votre schéma de base de données a changé et le nom n'est plus de type chaîne mais avec .ToString () votre code fonctionne toujours. Dans ce cas, il est donc préférable d'utiliser le type cast.

Voici l'implémentation de String.ToString () - rien de spécial =)

public override string ToString()
{
    return this;
}
16
Dzmitry Huba

Le downcasting est une opération relativement lente car le CLR doit effectuer diverses vérifications de type à l'exécution. Cependant, dans ce scénario particulier, la conversion en string est plus appropriée que d'appeler ToString() par souci de cohérence (vous ne pouvez pas appeler ToInt32 sur object, mais transformez-le en int) et maintenabilité.

5
Anton Gogolev

Je veux faire encore un commentaire

Si vous prévoyez d'utiliser cast: string name = (string) DataRowObject ["name"], vous obtiendrez une exception: impossible de caster un objet de type 'System.DBNull' en type'System.String 'au cas où l'enregistrement dans la table de base de données a une valeur nulle.

Dans ce scénario, vous devez utiliser: string name = DataRowObject ["name"]. ToString () or

Vous devez vérifier la valeur nulle comme

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";

}
4
SergoT

Pour l'objet de données, je vous suggère d'utiliser le mot clé "as" comme le code suivant.

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

Veuillez le vérifier avant d'utiliser la valeur.

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

Dans ce cas:

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

comme c'est un string, je pense que la méthode ToString() d'un objet chaîne est simple comme:

return this;

donc à mon humble avis il n'y a pas de pénalité de performance.

PS Je suis un programmeur Java, donc cette réponse n'est qu'une supposition.

2
dfa

Je sais que vous avez mentionné que l'objet est une chaîne, mais au cas où vous auriez peur que l'objet renvoyé soit nul, vous pouvez également transtyper en utilisant "Convert.ToString (DataRowObject [" name "]);" Cela a l'avantage supplémentaire de renvoyer une chaîne vide (string.empty) si l'objet est nul, pour éviter toute exception de référence nulle (à moins bien sûr que vous souhaitiez une exception levée dans de tels cas).

1
n00b

ToString () n'effectue pas de transtypage par défaut. Son but est de renvoyer une chaîne qui représente le type (par exemple "System.Object").

Si vous voulez éviter le casting, vous pouvez essayer de penser à une implémentation fortement typée (utilisant des génériques, par exemple) et évitant complètement DataRowObject.

1
martijn_himself