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

98,553

Solution 1

The two are intended for different purposes. The ToString method of any object is supposed to return a string representation of that object. Casting is quite different, and the 'as' key word performs a conditional cast, as has been said. The 'as' key word basically says "get me a reference of this type to that object if that object is this type" while ToString says "get me a string representation of that object". The result may be the same in some cases but the two should never be considered interchangeable because, as I said, they exist for different purposes. If your intention is to cast then you should always use a cast, NOT ToString.

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

see also http://bytes.com/groups/net-c/225365-tostring-string-cast

Solution 2

If you know it is a String then by all means cast it to a String. Casting your object is going to be faster than calling a virtual method.

Edit: Here are the results of some benchmarking:

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

I used Jon Skeet's BenchmarkHelper like this:

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

So it appears that casting is in fact slightly faster than calling ToString().

Solution 3

Basically in your case it is better to leave type cast because .ToString() may hide bugs. For example, your data base schema changed and name is no longer of string type but with .ToString() your code still works. So in this case it is better to use type cast.

Here is implementation of String.ToString() - nothing special =)

public override string ToString()
{
    return this;
}

Solution 4

I want to make one more comment

If you are going to use casting: string name = (string)DataRowObject["name"] you will get an Exception: Unable to cast object of type 'System.DBNull' to type'System.String' in case if the record in the database table has null value.

In this scenario you have to use: string name = DataRowObject["name"].ToString() or

You have to check for null value like

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

}

Solution 5

Downcasting is a relatively slow operation since CLR has to perform various runtime type-checks. However, in this particular scenario casting to string is more appropriate than calling ToString() for the sake of consistency (you can't call ToInt32 on object, but cast it to int) and maintanability.

Share:
98,553

Related videos on Youtube

David Božjak
Author by

David Božjak

Tech Manager at Storytel in Lund, Sweden.

Updated on July 05, 2022

Comments

  • David Božjak
    David Božjak almost 2 years

    This isn't really an issue, however I am curious. When I save a string in lets say an DataRow, it is cast to Object. When I want to use it, I have to cast it ToString. As far as I know there are several ways of doing this, first is

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

    and another one is:

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

    I am interested in what is the difference between both? Is the first more efficient? (This is just a speculation, in my head ToString() method is implemented by some looping mechanism where just casting it "could" be faster, however this is just a "gut feeling" I have).

    Is there even a faster / more elegant way of doing this?

    Can anyone clear this up for me?

    • n00b
      n00b about 11 years
      I know you mentioned that the Object is a string, but incase you're not sure afraid the returned object is null, you can also cast using "Convert.ToString(DataRowObject["name"]);" This has the added benefit of returning an empty string (string.empty) if the object is null, to avoid any null reference exceptions.
  • Jon Skeet
    Jon Skeet almost 15 years
    @Andrew: Have you benchmarked that? It may well have changed, but last time I benchmarked it I found that the virtual method was actually faster. I didn't expect it to be, but it was.
  • Andrew Hare
    Andrew Hare almost 15 years
    @Jon - No I didn't! I will have to check that out to make sure.
  • martijn_himself
    martijn_himself almost 15 years
    I think DataRowObject has no knowledge of types and stores everything as Objects, so it is definitely not as simple as return this.
  • fortran
    fortran almost 15 years
    @martjin_himself welcome to the world of Object Orientation, let me introduce you a new friend: Polymorphism.
  • Andrew Hare
    Andrew Hare almost 15 years
    It might not be as slow as you think - please see my answer.
  • martijn_himself
    martijn_himself almost 15 years
    @fortran would you mind elaborating? I am aware everything is an Object and polymorphism allows you to treat a string as if it were an Object, however that is irrelevant here, unless I am missing something? cheers
  • martijn_himself
    martijn_himself almost 15 years
    @dfa sorry what I meant to say is that it is not stored as a string, I wish I could edit comments if they sound a bit harsh :)
  • memnoch_proxy
    memnoch_proxy over 12 years
    would this be a more terse version of the same: string name = (row["name"] as string) ?? "default";
  • Remy
    Remy almost 11 years
    There is one additional benefit to using the "Convert.ToString" and that is that you can pass in a null value without having an exception thrown. link
  • TheGeekZn
    TheGeekZn about 10 years
    @AndrewHare- Jon's link leads to a 505
  • DaImTo
    DaImTo over 8 years
    So if I understand this correctly. .ToString will always return a string of the object. While casting will fail if it cant be returned as a string?
  • Andiana
    Andiana about 8 years
    @DaImTo: When you cast an object from type A to type B (if the casting) success, you will have a new object, which you can cast back to A type again. Casting is not change who they are (the core), but change what will they will be looked as. Converting, in common cases, is a one-way ticket. It make a new object (only) represent for the old object. Ex: a student object st when convert toString() will be a string look like student:@1343;43234. do you think you can turn it back into a student which have fields value?
  • Ashraf Alshahawy
    Ashraf Alshahawy about 7 years
    @Andiana In Ref Exam book for c# it says "When creating your own types, you can override ToString to return a string representation of your object. If necessary, you can then create a Parse and TryParse method that converts the string back to the original object. Implementing the IFormattable interface is required so that your object can be used by the Convert class." Could you explain it in the light of what you said earlier. Thank you
  • Jack Griffin
    Jack Griffin over 4 years
    Would string name = DataRowObject["name"] as String; work ? Just curious...