C # есть лучший способ написать это? - PullRequest
8 голосов
/ 09 февраля 2011
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)
{

Это обработчик ajax, проверяющий все переданные параметры в порядке.Это считается плохим, и есть ли лучший способ написать это, или это не так важно?

Ответы [ 6 ]

7 голосов
/ 09 февраля 2011

Если вы не собираетесь использовать отдельные переменные bool в другом месте, вы могли бы записать это как:

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

Вы можете захотеть извлечь int.TryParse(context.Request.QueryString[name], out variable в отдельный метод, оставив вам что-то вроде:

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

Кроме того, вы можете инкапсулировать все эти данные контекста в новый тип с помощью метода TryParse, так что вы получите что-то вроде:

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

Это, очевидно, больше работы, но я думаю, что это сделает код чище.

6 голосов
/ 09 февраля 2011

Да, начните с выделения вашего int.TryParse(etc.) в отдельную функцию.

(возможно, под сильным влиянием 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);
}

Тогда:

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

Чтобы сделать вещи немного яснее, вы могли бы

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)
3 голосов
/ 09 февраля 2011

Я бы, наверное, пошел на такой формат


int uploadsID, pageNumber, x, y, h;

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

но я не вижу ничего плохого в вашем подходе.

2 голосов
/ 09 февраля 2011

Одна вещь, которую вы можете сделать, это заменить это:

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

На это

int uploadsID, pageNumber, x, y, w, h;
1 голос
/ 09 февраля 2011
try
{
    // use Parse instead of TryParse

    // all are valid, proceed
}
catch
{
    // at least one is not valid
}
0 голосов
/ 09 февраля 2011

Вы можете написать помощника, который избавится от уродливого out стиля передачи TryParse, например:

public delegate bool TryParser<T>(string text, out T result) where T : struct;

public static T? TryParse<T>(string text, TryParser<T> tryParser)
                             where T : struct
{
    // null checks here.
    T result;
    return tryParser(text, out result) ? result : new T?();
}

И затем (при условии, что вас интересует только валидность):

bool isValid = new [] { "uploadID" , "page", "x", "y", "w", "h" }
              .Select(q => context.Request.QueryString[q])
              .All(t => TryParse<int>(t, int.TryParse).HasValue);

Если вам нужны отдельные значения:

var numsByKey = new [] { "uploadID" , "page", "x", "y", "w", "h" }
               .ToDictionary(q => q,
                             q => TryParse<int>(context.Request.QueryString[q], 
                                                int.TryParse));

bool isValid = numsByKey.Values.All(n => n.HasValue);

Это сохраняет почти ту же информацию, что и раньше, за исключением того, что для детальной информации требуется поиск, а не доступ к локальной переменной.

...