2

Update:


When a database returns a value through the scalar, it will always be an object. So when the value is returned you should have a preconceived notion of what the type will be. Why would you use ToString(); when you you have a SELECT which passes two parameters.

As if it doesn't exist it will always throw a null. So in my refactor I believed the as would be the proper approach. As ToString() will throw an error --- So what form of cast is it comparable to?


I've got some code I'm maintaining, but in apart of my refactor I came across a ToString() attached to an ExecuteScalar. My question would be, does the usage of ToString() equate to:

(string)command.ExecuteScalar();

Or would it represent this:

command.ExecuteScalar() as string;

Obviously the as string would fail gracefully, where the cast (string) would actually fall into an InvalidCastException. So when you call:

command.ExecuteScalar().ToString();

Which method of casting is it attempting to do?

Greg
  • 11,302
  • 2
  • 48
  • 79
  • 3
    Keep in mind that ExecuteScalar could return null. – Steve Aug 26 '14 at 17:29
  • 3
    What does ExecuteScalar return? (System.Object.) Is there documentation on System.Object.ToString() anywhere on the internet? (Yes.) Let alone testing your own code, what research did you do? – Anthony Pegram Aug 26 '14 at 17:32
  • @Greg, Why have you have not consider Convert.ToString()? – Shah Aug 26 '14 at 17:35
  • 1
    [This][1] answer may help you to understand the difference: [1]: http://stackoverflow.com/questions/1170756/casting-vs-converting-an-object-tostring-when-object-really-is-a-string – Jeff Anderson Aug 26 '14 at 17:36

4 Answers4

10

No, it doesn't mean either of those - it simply means calling ToString() on whatever the value is.

In particular, if the value is not a string, it will convert it to a string anyway - whereas string would fail with InvalidCastException and the as would return null.

So for example:

object x = 10;
string a = x.ToString(); // "10"
string b = x as string; // null
string c = (string) x; // Bang

Of course, ToString() can still throw an exception too - most obviously if the target of the call is a null reference.

Personally, I would suggest using a cast if you know what the result type should be - although the result of ExecuteScalar is more commonly a numeric value (e.g. a count) rather than a string.

Yes, that means an exception will be thrown if you're wrong - but if your query isn't doing what it's meant to anyway, then stopping due to an exception may well be better than going ahead with a bogus view of the world. (See my blog post on casting vs as for more on this attitude.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • With the ExecuteScalar, you need to compensate for DbNull as well via `var x = blah.ExecuteScalar();` `var y = x == DbNull.Value ? null : (int) x;` right? – Codeman Aug 26 '14 at 17:33
  • In your example, which of those options would the run-time choose if we used the code `String.Concat(x,"")` which in theory would both give us a string and avoid a null reference in all cases? – xDaevax Aug 26 '14 at 17:33
  • @Pheonixblade9: Quite possibly, depending on context. – Jon Skeet Aug 26 '14 at 17:34
  • @xDaevax: I'm not sure what you mean by "which of those options would the runtime choose" - it would call `string.Concat(object, object)` and would call `ToString` on each non-null argument. – Jon Skeet Aug 26 '14 at 17:35
  • I definitely have to compensate for DBNull in a lot of our code, so I thought it was worth mentioning :) When you say context, are you saying it could be different depending on RDBMS or different depending on something else? – Codeman Aug 26 '14 at 17:38
  • @Pheonixblade9: I'm saying that if the query is *actually* performing a count, for example, it might never be null. – Jon Skeet Aug 26 '14 at 17:40
  • I see. I did not know that was the behavior of the Concat method. Thanks for the clarification. – xDaevax Aug 26 '14 at 17:51
7

Neither, because Object.ToString() will returns you a string representation of the object. Regardless whether the query returns a varchar or int.

Xiaoy312
  • 14,292
  • 1
  • 32
  • 44
1

If command.ExecuteScalar() returns null then it would be something like null.ToString() which will break your production code.

also (string)command.ExecuteScalar() can break your code.

I would suggest to use below line

var result = command.ExecuteScalar() as string;
if(result != null)
{
  //your code
}
Vimal CK
  • 3,543
  • 1
  • 26
  • 47
1

Let's think about it for a bit.

When you do command.ExecuteScalar() you get back and object in a lot of cases based on the provider you get an int.

What happens is the order of operations triggers

  • Command.ExecuteScalar() gets and object back.
  • We are assuming he is an int for the excercise we get that int back.
  • To String gets called which is defined in the int32 object itself.
  • You get back the string that was determined inside.

For the most part toString is not meant to throw an exception if no one has implemented in the chain you just get the object type back which is the implementation on the object.

With that said in the case of the int it would probably be the one above. Note if execute scalar returns null to string will error out since null is not an object.

Hope that helps.

P.S. If you tell me the object type of ExecuteScalar i can give you a better answer.

Alfredo Alvarez
  • 336
  • 3
  • 15