Bookmark and Share

TryParse vs Convert

Since I’ve been coming out against out params, I sometimes get asked about the TryParse pattern. My typical response is that the most egregious offenses of out param usage occur when there is more than one, but even one should be avoided. However, I was recently presented with a more specific question: “lets say you had to pick up a query string param in WebForms/ASP.NET and make it an Int32... would use Convert or TryParse?” This is a very practical question, and given the choices it is interesting to examine for the best practice.

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 { }

Yuck.

Maybe

In the response to the question on which method of parsing the query string param I would use, I rejected both typical solutions. They both have flaws I find distasteful. Why not parse the string and return a Nullable<T> so the caller can decide what to do with it?

int index = Maybe.ToInt32(Request.QueryString["index"]) ?? 0;

Simple and declarative. Maybe’s methods wrap the TryParse methods since they appear to be more efficient than Convert’s methods. The idea is that complexity should be hidden, and code should be made more declarative. I believe the Maybe class achieves it. The name was chosen because a non-generic Nullable class already exists, and Maybe seemed a sound choice since it may be a value or it may be nothing.

Conversion Failures

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.

Download the source code from kodefu.codeplex.com.

blog comments powered by Disqus

KodefuGuru.GetInfo()

Chris Eargle
LinkedIn Twitter Technorati Facebook

Chris Eargle
Telerik Developer Evangelist, C# MVP

JustCode

Telerik .NET Ninja

 

INETA Community Speakers Program

 

MVP - Visual C#

 

Friend of RedGate

World Map

Tag cloud

Month List

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.