Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# is there a nicer way of writing this?

int uploadsID;
int pageNumber;
int x;
int y;
int w;
int h;

bool isValidUploadID = int.TryParse(context.Request.QueryString["uploadID"], out uploadsID);
bool isValidPage = int.TryParse(context.Request.QueryString["page"], out pageNumber);
bool isValidX = int.TryParse(context.Request.QueryString["x"], out x);
bool isValidY = int.TryParse(context.Request.QueryString["y"], out y);
bool isValidW = int.TryParse(context.Request.QueryString["w"], out w);
bool isValidH = int.TryParse(context.Request.QueryString["h"], out h);

if (isValidUploadID && isValidPage && isValidX && isValidY & isValidW & isValidH)
{

This is an ajax handler, checking all passed params are OK. Is this considered bad, and is there a better way to write this, or is it not that important?

like image 816
Tom Gullen Avatar asked Feb 09 '11 10:02

Tom Gullen


2 Answers

Assuming you're not going to use the individual bool variables elsewhere, you could write that as:

int uploadsID, pageNumber, x, y, w, h;
if (int.TryParse(context.Request.QueryString["uploadID"], out uploadsID) &&
    int.TryParse(context.Request.QueryString["page"], out pageNumber) &&
    int.TryParse(context.Request.QueryString["x"], out x) &&
    int.TryParse(context.Request.QueryString["y"], out y) &&
    int.TryParse(context.Request.QueryString["w"], out w) &&
    int.TryParse(context.Request.QueryString["h"], out h))
{
}

You may want to extract out int.TryParse(context.Request.QueryString[name], out variable into a separate method, leaving you with something like:

int uploadsID, pageNumber, x, y, w, h;
if (TryParseContextInt32("uploadID", out uploadsID) &&
    TryParseContextInt32("page", out pageNumber) &&
    TryParseContextInt32("x", out x) &&
    TryParseContextInt32("y", out y) &&
    TryParseContextInt32("w", out w) &&
    TryParseContextInt32("h", out h))
{
}

Alternatively, you could encapsulate all this context data into a new type with a TryParse method, so you'd have something like:

PageDetails details;
if (PageDetails.TryParse(context.Request.QueryString))
{
    // Now access details.Page, details.UploadID etc
}

That's obviously more work, but I think it would make the code cleaner.

like image 87
Jon Skeet Avatar answered Sep 19 '22 14:09

Jon Skeet


Yes, start by factoring out your int.TryParse(etc.) into a separate function.

(Possibly over-influenced by F#)

//return a tuple (valid, value) from querystring of context, indexed with key
private Tuple<bool, int> TryGet(HttpContext context, string key)
{
    int val = 0;
    bool ok = int.TryParse(context.request.QueryString[key], out val);
    return Tuple.New(ok, val);
}

Then:

var UploadId = TryGet(context, "uploadID");
//...
if(UploadId.Item1 && etc..) 
{
    //do something with UploadId.Item2;

To make things slightly clearer, you could

private class ValidValue
{
    public bool Valid { get; private set; }
    public int Value { get; private set; }
    public ValidValue(bool valid, int value)
    { 
        Valid = valid;
        Value = value;
    }
    //etc., but this seems a bit too much like hard work, and you don't get 
    // equality for free as you would with Tuple, (if you need it)
like image 44
Benjol Avatar answered Sep 18 '22 14:09

Benjol