tags:

views:

804

answers:

7

Hello

is there some way of return null if it can't parse a string to int?

with:

public .... , string? categoryID) 
{
int.TryParse(categoryID, out categoryID);

getting "cannot convert from 'out string' to 'out int'

what to do?

EDIT:

No longer relevant because of asp.net constraints is the way to solve problem

/M

A: 

** this answer was down-voted a lot ** Although it is a possible solution - it is a bad one performance wise, and probably not a good programming choice.

I will not delete it, as I guess many programmers might not be aware of this, so here is an example how not to do things:

use try and catch

try
{
res = Int32.Parse(strVAR)
}
catch(exception ex) 
{
 return null;
}
Dani
Better to use `TryParse`.
Jason
Well, this is still an option....
Dani
Since C# 2.0 came out, TryParse is almost always better than doing exception catching.
Bomlin
It's an option, but it's a bad one - hence all the downvotes.
Jon Skeet
I will be happy to understand why it is bad (performance ?) ?
Dani
@Dani: There are lots of options. Some of them aren't good.
Jason
and if you pass null to TryParse ... ?
Dani
Exceptions should not, as a practice, be a part of the normal flow of code. They should be exactly as their name implies, an exception. If you are expecting certain things on a regular basis, you should try to code a solution rather than throwing an exception and handling it. An example is checking if a file exists prior to trying to open it rather than opening a file and catching a file not found exception. So in general, avoid exception programming if you don't need it. In other words, save it for the exceptions... :)
Bomlin
@Dani: Yes, throwing and catching exceptions is expensive. Second, exceptions are meant, well, for exceptional situations. If bad input is routinely expected then it should be handled outside of the exception framework.
Jason
Make sense, I wonder though if TryParse doesn't use a try/catch mechanism internally. Although, if it throws exception on null input, probably not...
Dani
Yes, it has performance implications. When an exception is thrown, a stack crawl must be performed which can be very slow. Just try it in LINQPad yourself - call your code (with bad data) in a loop 1000 times vs. the TryParse method and observe the difference. On my system it's over 350 times slower to use your method.
Josh Einstein
(And in my test it was a *very* small call stack.)
Josh Einstein
@Dani: No, `TryParse` does not use a `try/catch` mechanism internally. That would defeat the purpose. You can verify this using reflection. What I find interesting is that `Parse` does not use `TryParse` internally. It seems that the obvious way to write `Parse` is to call `TryParse` and throw an exception when `TryParse` returns `false`.
Jason
Hmm... it might do problems compiling against older dot net versions.
Dani
Anyways - I've changed the answer to reflect this discussion, but I did not delete it, as it is important for this info to stay here.
Dani
+1 for leaving it here as an example. (It's at -5 now.) Sure, using exceptions as flow control is bad, as Dani acknowledges, but I think we've made our point. (+1 also for the humble response to the downvotes and criticism.)
John M Gant
@Jason: Well, I'd say that `TryParse` is for scenarios where bad input is more or less expected (e.g., user input) whereas if you call `Parse` you are deciding to expect good input (e.g., reading from a reliable data source). If `TryParse` introduces *any* overhead (which it must, if only in the form of some minor logic), then `Parse` will be faster for good input. I could be wrong, of course, but that'd be my guess.
Dan Tao
+1 Because although it's incorrect, it does show a valid way that someone could solve a problem such as this. Since the poster edited his answer to show that it was incorrect, and left comments as to why, I see no reason that it should be given such a low ranking.
Greg Bahrey
@Dan, it's a good point. but I guess good programming should not assumes that the "source" is reliable. (I can think about a scenario of data that was created using Integer numbers moved ToString(), so in cases like that you might be right).
Dani
+1 for standing your ground and leaving it here as an example of what not to do.
Nescio
A: 

Int is a value type which means there is no such thing as a null int. So no, TryParse will never alter the out parameter so that it is null.

But the problem you're having is you're passing a string to the out parameter of TryParse when its expecting an integer.

You need something like this...

Int categoryID = 0;
string strCategoryID = "somestringmaybeitsaninteger";

int.TryParse(strCategoryID, out categoryID);
Jason Punyon
There is a nullable int: int?
Dani
Dani: `TryParse` however, returns `int`, not `Nullable<int>`.
Joey
int? is not actually an integer type ... it's shorthand for System.Nullable<int>.
jerhinesmith
A: 

TryParse will return false if the string can't be parsed. You can use this fact to return either the parsed value, or null. Anyway I guess that you are intending to return int? from your method, then it would be something like this:

public int? ParseInt(string categoryID) 
{
    int theIntValue;
    bool parseOk = int.TryParse(categoryID, out theIntValue);
    if(parseOk) {
        return theIntValue;
    } else {
        return null;
    }
}
Konamiman
+9  A: 

Here's a proper use of Int32.TryParse:

int? value;
int dummy;
if(Int32.TryParse(categoryID, out dummy)) {
    value = dummy;
}
else {
    value = null;
}
return value;
Jason
Or: value = int.TryParse(categoryID, out dummy) ? dummy : null;
Dan Tao
Yes, absolutely but that's more opaque to a neophyte.
Jason
@Dan: won’t compile ;-) But yes, I prefer that solution (plus one cast, to make it compile).
Konrad Rudolph
A: 

Do you want to do something like this?

public int? Parse(string categoryID) 
{
  int value;
  if (int.TryParse(categoryID, out value))
  {
    return value;
  }
  else
  {
    return null;
  }
}
Stefan Steinegger
+4  A: 

First of all, why are you trying to parse a string to an int and stick the result back into a string?

The method signature is

bool int.TryParse(string, out int)

so you have to give an int as second argument. This also means that you won't get null if parsing fails, instead the method will simply return false. But you can easily piece that together:

int? TryParse2(string s) {
    int i;
    if (!int.TryParse(s, out i)) {
        return null;
    } else {
        return i;
    }
}
Joey
Eep, thanks, Garry. Writing code without ever compiling it invites errors such as those :-)
Joey
+3  A: 

How about this?

public int? ParseToNull(string categoryId)
{
    int id;
    return int.TryParse(categoryId, out id) ? (int?)id : null;
}
Greg Bahrey
This solution might benefit from being turned into an extension method.
Martin Clarke
It's already an extension method in my app but I didn't know what molgan wanted it for so I kept it as a method.
Greg Bahrey