TryParse

int index;
int.TryParse(Request.QueryString["index"], out index);

This version isn’t so bad since it requires no conditional processing. The problem with the TryParse method is the out parameter, which requires the initial declaration of variable whether or not you want or need it. This also prevents it from being used in a declarative statement, since the return value is whether the value was parsed. This can be used declaratively using the ternary operator, but it is rather odd since the result is already defined. Many people opt to use imperative logic instead, testing for !<t>.TryParse.

Here’s are examples of non-zero default value. The first using an if statement and the second with the ternary operator.

int index;
if (!int.TryParse(Request.QueryString["index"], out index))
{
    index = 1;
}
int index;
index = int.TryParse(Request.QueryString["index"], outindex) ? index : 1;

Convert

var index = Convert.ToInt32(Request.QueryString["index"]);

Convert is more declarative in this form, but it has a fatal flaw. If the string being parsed is an invalid value (not null, but something like “asdf”), then it will throw an exception. Exceptions are expensive, and it requires wrapping the code in a try… catch block since the exception is typically meaningless aside from preventing the assignment. Perhaps the above statement would be better expressed as:

int index = 0;
try
{
    index = Convert.ToInt32(Request.QueryString["index"]);
}
catch { }

The typical conversion failure use case is to assign a default value. However, additional logic is sometimes necessary. With TryParse, you test the return value for false. With Convert, you catch the exception. With Maybe, you test for null.

int? result = Maybe.ToInt32(Request.QueryString["index"]); if (result == null) { // Failure processing }

Since it is sometimes necessary to know if a the parsing was successful, I didn’t opt to create a ParseWithDefault method.