77

What is the difference between using the two following statements? It appears to me that the first "as string" is a type cast, while the second ToString is an actual call to a method that converts the input to a string? Just looking for some insight if any.

Page.Theme = Session["SessionTheme"] as string;
Page.Theme = Session["SessionTheme"].ToString();
Oded
  • 489,969
  • 99
  • 883
  • 1,009
jaywon
  • 8,164
  • 10
  • 39
  • 47
  • Possible duplicate of [Casting vs Converting an object toString, when object really is a string](http://stackoverflow.com/questions/1170756/casting-vs-converting-an-object-tostring-when-object-really-is-a-string) – Jim Fell May 24 '16 at 17:36

9 Answers9

109

If Session["SessionTheme"] is not a string, as string will return null.

.ToString() will try to convert any other type to string by calling the object's ToString() method. For most built-in types this will return the object converted to a string, but for custom types without a specific .ToString() method, it will return the name of the type of the object.

object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;

string s = o1 as string;  // returns "somestring"
string s = o1.ToString(); // returns "somestring"
string s = o2 as string;  // returns null
string s = o2.ToString(); // returns "1"
string s = o3 as string;  // returns null
string s = o3.ToString(); // returns "System.Object"
string s = o4 as string;  // returns null
string s = o4.ToString(); // throws NullReferenceException

Another important thing to keep in mind is that if the object is null, calling .ToString() will throw an exception, but as string will simply return null.

Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223
  • 2
    `ToString()` will 'try to convert any other type to string'? With most built-in types, yes. With your own custom stuff in Session, say a complex User object, all depends whether you've overriden `ToString()` and how you've implemented it in your class. If not implemented it returns the type info string. – Wim Jan 20 '10 at 08:42
  • 2
    Yes, of course. But the point here is to illustrate the difference between ToString() and "as string". If I want to provide a complete answer, it would be 2 pages long – Philippe Leybaert Jan 20 '10 at 08:44
  • 4
    My comment explains it. That's not 2 pages long. It's about being *accurate*. – Wim Jan 20 '10 at 08:45
  • I added a few lines to my answer – Philippe Leybaert Jan 20 '10 at 08:54
  • 4
    @Wim: being accurate can sometimes confuse the OP. Which doesn't mean accuracy is not a good thing, but sometimes it's better to keep an answer short – Philippe Leybaert Jan 20 '10 at 08:57
  • 1
    appreciate both your guys comments :) Thanks! – jaywon Jan 20 '10 at 08:58
  • 1
    what would you say about this `string s =o2?.ToString()` – Fortune Jun 10 '18 at 11:28
15

The as keyword will basically check whether the object is an instance of the type, using MSIL opcode isinst under the hood. If it is, it returns the reference to the object, else a null reference.

It does not, as many say, attempt to perform a cast as such - which implies some kind of exception handling. Not so.

ToString(), simply calls the object's ToString() method, either a custom one implemented by the class (which for most in-built types performs a conversion to string) - or if none provided, the base class object's one, returning type info.

Wim
  • 11,998
  • 1
  • 34
  • 57
7
Page.Theme = Session["SessionTheme"] as string;

tries to cast to a string

whereas

Page.Theme = Session["SessionTheme"].ToString();

calls the ToString() method, which can be anything really. This method doesn't cast, it should return a string representation of this object.

d219
  • 2,707
  • 5
  • 31
  • 36
Oxymoron
  • 1,382
  • 4
  • 20
  • 40
7

I'm extending Philippe Leybaert's accepted answer a bit because while I have found resources comparing three of these, I've never found an explanation that compares all four.

  • (string)obj
  • obj as string
  • obj.ToString()
  • Convert.ToString(obj)
object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;

Console.WriteLine((string)o1);           // returns "somestring"
Console.WriteLine(o1 as string);         // returns "somestring"
Console.WriteLine(o1.ToString());        // returns "somestring"
Console.WriteLine(Convert.ToString(o1)); // returns "somestring"
Console.WriteLine((string)o2);           // throws System.InvalidCastException
Console.WriteLine(o2 as string);         // returns null
Console.WriteLine(o2.ToString());        // returns "1"
Console.WriteLine(Convert.ToString(o2)); // returns "1"
Console.WriteLine((string)o3);           // throws System.InvalidCastException
Console.WriteLine(o3 as string);         // returns null
Console.WriteLine(o3.ToString());        // returns "System.Object"
Console.WriteLine(Convert.ToString(o3)); // returns "System.Object"
Console.WriteLine((string)o4);           // returns null
Console.WriteLine(o4 as string);         // returns null
Console.WriteLine(o4.ToString());        // throws System.NullReferenceException
Console.WriteLine(Convert.ToString(o4)); // returns string.Empty

From these results we can see that (string)obj and obj as string behave the same way as each other when obj is a string or null; otherwise (string)obj will throw an invalid cast exception and obj as string will just return null. obj.ToString() and Convert.ToString(obj) also behave the same way as each other except when obj is null, in which case obj.ToString() will throw a null reference exception and Convert.ToString(obj) will return an empty string.

So here are my recommendations:

  • (string)obj works best if you want to throw exceptions for types that can't be assigned to a string variable (which includes null)
  • obj as string works best if you don't want to throw any exceptions and also don't want string representations of non-strings
  • obj.ToString() works best if you want to throw exceptions for null
  • Convert.ToString(obj) works best if you don't want to throw any exceptions and want string representations of non-strings

EDIT: I've discovered that Convert.ToString() actually treats null differently depending on the overload, so it actually matters that the variable was declared as an object in this example. If you call Convert.ToString() on a string variable that's null then it will return null instead of string.Empty.

Kyle Delaney
  • 11,616
  • 6
  • 39
  • 66
5

To confuse the matter further, C# 6.0 has introduced the null-conditional operator. So now this can also be written as:

Page.Theme = Session["SessionTheme"]?.ToString();

Which will return either null or the result from ToString() without throwing an exception.

Mike Lowery
  • 2,630
  • 4
  • 34
  • 44
  • While this is useful, not sure how it directly answers the question of the difference between `as string` and `.ToString()`. – crashmstr Sep 15 '15 at 16:07
4

First of all "any-object as string" and "any-object.ToString()" are completely different things in terms of their respective context.

string str = any-object as string;

1) This will cast any-object as string type and if any-object is not castable to string then this statement will return null without throwing any exception.
2) This is a compiler-service.
3) This works pretty much well for any other type other than string, ex: you can do it as any-object as Employee, where Employee is a class defined in your library.

string str = any-object.ToString();  

1) This will call ToString() of any-object from type-defination. Since System.Object defines ToString() method any class in .Net framework has ToString() method available for over-riding. The programmer will over-ride the ToString() in any-object class or struct defination and will write the code that return suitable string representation of any-object according to responsibility and role played by any-object.
2) Like you can define a class Employee and over-ride ToString() method which may return Employee object's string representation as "FIRSTNAME - LASTNAME, EMP-CDOE" .

Note that the programmer has control over ToString() in this case and it has got nothing to do with casting or type-conversion.

this. __curious_geek
  • 42,787
  • 22
  • 113
  • 137
1

The as string check is the object is a string. If it isn't a null it returned.

The call to ToString() will indeed call the ToString() method on the object.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 1
    It doesn't attempt to cast. It checks whether the class is an instance of the specified type and returns the reference if so, else null. – Wim Jan 20 '10 at 08:35
1

The first one returns the class as a string if the class is a string or derived from a string (returns null if unsuccessful).

The second invokes the ToString() method on the class.

rein
  • 32,967
  • 23
  • 82
  • 106
0

Actually the best way of writing the code above is to do the following:

if (Session["SessionTheme"] != null)
{
    Page.Theme = Session["SessionTheme"].ToString();
}

That way you're almost certain that it won't cast a NullReferenceException.

mortenbpost
  • 1,687
  • 16
  • 22