3

Is there a difference between DataReader[0].ToString() and (string)DataReader[0]?

My guess is that (string)DataReader[0] might fail if the database type isn't a string type, where DataReader[0].ToString() would just convert anything outside of a DB null to a string. Is that the case?

Which would be faster?

Tim Coker
  • 6,484
  • 2
  • 31
  • 62
  • 1
    As a bit of fun, I would add `Convert.ToString(DataReader[0]);` :-) – Steven Ryssaert May 12 '11 at 13:09
  • 1
    "would just convert anything outside of a DB null to a string" Actually, `DBNull.Value` does have a `ToString()` as it's an actual object, so you can call `ToString()` on it and it'll work fine. – BoltClock May 12 '11 at 13:10
  • But if DataReader[0] is null in the DB, `ToString()` would throw an exception is what I mean. – Tim Coker May 12 '11 at 13:13

3 Answers3

2

Those both introduce you to potential data exceptions, IMO the optimal way to read from a reader is:

var x = reader[0] as string

Then for numbers / bools etc I always use nullable types so you can get

var y = reader[1] as int?

Now if you absolutely are as opposed to nullables for some reason (I think they're great for knowing whether something is or not set)

int i = (reader[1] as int?).GetValueOrDefault()

Chris Marisic
  • 32,487
  • 24
  • 164
  • 258
  • 7
    If you're *expecting* a string value and you end up getting (say) an integer, I'd rather see an exception than keep going as if we *really* had a `null` value. – Jon Skeet May 12 '11 at 13:10
  • What data exception can happen with `ToString()`? – fearofawhackplanet May 12 '11 at 13:12
  • try `((string)null).ToString()` ;) – Chris Marisic May 12 '11 at 13:13
  • 1
    I agree with Jon. *Know your data.* – Anthony Pegram May 12 '11 at 13:14
  • 1
    @fearofawhackplanet `ToString()` will throw a null reference exception if the object you're calling it on is null. Outside of that, it will return SOMETHING every time. (unless you have a screwed up override on a custom object's `ToString()`) – Tim Coker May 12 '11 at 13:14
  • I've never once encountered a `DataReader` returning `null` (as opposed to `DBNull.Value`). Under what circumstances does this occur? – fearofawhackplanet May 12 '11 at 13:15
  • @Jon Skeet I'd rather get a ticket that says a spot on a page is blank somewhere than the entire page (or potentially site) is blowing up from a data issue. – Chris Marisic May 12 '11 at 13:16
  • 2
    @Chris: Whereas I'd rather have a blank page than overwrite someone's bank account with empty data. If something is wrong, *abort as quickly as possible*. Continuing with bad data is a really bad idea. – Jon Skeet May 12 '11 at 13:18
  • @fearofawhackplanet IDK off hand however back in 2006 on 2.0 when I was at a shop that the dal's were all data readers we had issues with that, could've been related to the oracle client sucking /shrug. – Chris Marisic May 12 '11 at 13:19
  • @Jon Skeet why would you be depending on you DAL mapping to enforce data integrity? It should just load objects without fail. If data integrity is a concern validate the constructed object after it's been loaded. I'd much rather validate business information than random cast errors or NREs. I'd build code contracts and enforce them before I return the object to adamantly enforce data integrity. Regardless most of this is a nonissue anyway, if null is unacceptable for a value coming back from an edit screen you should hit validation anyway and the user can fix the value. – Chris Marisic May 12 '11 at 13:27
  • 2
    @Chris: Well `null` might be a valid value for the data - but it's not what's *actually* in the database, due to a schema problem. Why would you want to ignore the schema being out of whack? Fundamentally, we can *easily* discover the error at exactly this point - why defer error handling, and risk that we won't spot the problem later on? Again, I maintain that failing as soon as you spot that something is seriously wrong is the best approach in most scenarios. – Jon Skeet May 12 '11 at 13:29
  • @Jon Skeet if the schema was that substantially off, querying probably wouldn't work in the first place. If it was only 1 column that was completely screwed up, inserts would blow up on it. I care about data integrity to validate against business criteria during alterations, read actions shouldn't blow up on me. – Chris Marisic May 12 '11 at 13:42
  • @Chris: And if you're using data read from one table to generate a report elsewhere? You haven't changed my mind about it being a good idea to continue with detectable-but-possibly-undetected errors. – Jon Skeet May 12 '11 at 13:44
  • @Jon Skeet that's a perfect example of why I don't want it to blow up. That report will be able to be produced, and there will be holes in the report. (or entire columns missing) which allows the acknowledgement that there is something wrong but there is not a total outage. That's like saying you'd rather have a black out for a whole city because a power line went down. Partial availability is generally better than zero. Now if the data is integral to the application being able to function, then yes it should bring it down. But data as data shouldn't crash my application. – Chris Marisic May 12 '11 at 13:56
  • 1
    @Chris: Holes like possibly "Nope, apparently we haven't sold anything this year. Our income is 0" - because the data type was wrong. Pretending something is working when it's not is unacceptable IMO. It's not "data as data" being wrong - it's the *schema* being wrong here. – Jon Skeet May 12 '11 at 14:00
  • @Jon Skeet now you're just being disingenuous "Holes like... we haven't sold anything this year", any business person that would see that report would find it highly suspect (or the company needs new business people) and inquire on it. A more realistic take on that would be they can see all they sold but every price is $0 or blank for doing say reader[0] as double? when the type in the database is decimal, or gets set with some kind of crazy precision / custom db type that doesn't play nice in .NET. – Chris Marisic May 12 '11 at 14:24
  • 1
    @Chris: I would personally rather tell someone that something was wrong with the system than present them with a report which is obviously incorrect but which I (as the system) am claiming is correct. Presenting incorrect data as if it were correct looks awful, IMO... and it can also delay the error being found, if instead of being obvious it's actually quite subtle. – Jon Skeet May 12 '11 at 14:49
  • Two answers and a lot of comments but which one is faster... casting `(string)` or `ToString()`? – Junior Mayhé Dec 08 '11 at 00:24
  • @JuniorMayhé `as` casting is always fastest, we're talking trivial differences because doing (string) will cause if(x is string) then cast, when as will just do it. Calling ToString() will probably do the (string) cast but with risk of null reference exception. – Chris Marisic Dec 08 '11 at 14:59
0

I know its too late to comment on this question but I think many people have the similar doubt about (string)object and object.ToString() and this question is the correct place to comment on.

When its sure that the type of object is string then its better to do a typecasting rather than calling a method .ToString(). If you look into the code of ToString() :

    public virtual string ToString()
    {
      return this.GetType().ToString();
    }

Which is first finding the type of object by calling GetType() method then calling the ToString() of that type.

If we are not sure about the type of object then the answer would be do ToString() instead of (string).

If you wanted to see the benchmark of performance of (string) vs .ToString() then follow the link : (string) vs .ToString()

Community
  • 1
  • 1
Ranjit Singh
  • 3,715
  • 1
  • 21
  • 35
0

(string)DataReader[0] is typecasting. The compiler will insert some set of instructions at compile time that needs to be executed in order to perform the conversion and throws an exception when it fails to do so.

DataReader[0].tostring() is function call which gets resolved at runtime and no exceptions.

Experts please correct me if I am wrong.

Sandeep
  • 7,156
  • 12
  • 45
  • 57