13

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

jason
  • 236,483
  • 35
  • 423
  • 525
Lasse Edsvik
  • 9,070
  • 16
  • 73
  • 109
  • 2
    Why do you parse it to an int when you want to store it in a string?? – Stefan Steinegger Nov 13 '09 at 14:17
  • 2
    By the way, string is a reference type, so you should not make it nullable. (does this compile anyway?) – Stefan Steinegger Nov 13 '09 at 14:17
  • I use this for asp.net mvc so the categoryID is mapped from the url, so I get error if i pass in string in url – Lasse Edsvik Nov 13 '09 at 14:20
  • @Stefan: My guess is that the OP is validating string format using this method as well as enforcing a fixed string format. Therefore, they can parse 10,000 and turn it into 10000, for example. Just a guess though. – Jeff Yates Nov 13 '09 at 14:29

8 Answers8

28

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 a variable of type 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
  • 344,408
  • 85
  • 689
  • 683
14

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
  • 236,483
  • 35
  • 423
  • 525
10

How about this?

public int? ParseToNull(string categoryId)
{
    int id;
    return int.TryParse(categoryId, out id) ? (int?)id : null;
}
DigitalNomad
  • 428
  • 1
  • 3
  • 18
2

Simplest and one-liner...

int N = int.TryParse(somestring, out N) ? N : 0;

It works 'cause it's evaluated left to right. Null not so easy.

John C
  • 3,052
  • 3
  • 34
  • 47
0

** 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
  • 14,639
  • 11
  • 62
  • 110
  • 1
    Since C# 2.0 came out, TryParse is almost always better than doing exception catching. – Bomlin Nov 13 '09 at 14:20
  • It's an option, but it's a bad one - hence all the downvotes. – Jon Skeet Nov 13 '09 at 14:21
  • I will be happy to understand why it is bad (performance ?) ? – Dani Nov 13 '09 at 14:22
  • and if you pass null to TryParse ... ? – Dani Nov 13 '09 at 14:25
  • 2
    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 Nov 13 '09 at 14:26
  • @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 Nov 13 '09 at 14:28
  • 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 Nov 13 '09 at 14:31
  • 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 Nov 13 '09 at 14:33
  • (And in my test it was a *very* small call stack.) – Josh Nov 13 '09 at 14:34
  • @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 Nov 13 '09 at 14:38
  • Hmm... it might do problems compiling against older dot net versions. – Dani Nov 13 '09 at 14:39
  • 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 Nov 13 '09 at 14:47
  • +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 Nov 13 '09 at 14:59
  • @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 Nov 13 '09 at 15:01
  • 4
    +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. – DigitalNomad Nov 13 '09 at 15:42
  • @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 Nov 13 '09 at 16:05
  • +1 for standing your ground and leaving it here as an example of what not to do. – Nescio Nov 13 '09 at 18:16
0

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);
Restore the Data Dumps
  • 38,967
  • 12
  • 96
  • 122
0

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
  • 49,681
  • 17
  • 108
  • 138
0

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
  • 63,782
  • 15
  • 129
  • 193