Общий метод анализа без бокса

Я пытаюсь написать универсальный метод Parse, который преобразует и возвращает строго типизированное значение из NamedValueCollection. Я попробовал два метода, но оба эти метода проходят через бокс и распаковку, чтобы получить значение. Кто-нибудь знает способ избежать бокса? Если бы вы увидели это в производстве, вам бы не понравилось, насколько это плохо для производительности?

Использование:

var id = Request.QueryString.Parse<int>("id");

Попытка №1:

public static T Parse<T>(this NameValueCollection col, string key)
{
    string value = col[key];

    if (string.IsNullOrEmpty(value))
        return default(T);

    if (typeof(T) == typeof(int))
    {
        //return int.Parse(value); // cannot convert int to T
        //return (T)int.Parse(value); // cannot convert int to T
        return (T)(object)int.Parse(value); // works but boxes
    }
    if (typeof(T) == typeof(long))
    {
        return (T)(object)long.Parse(value); // works but boxes
    }
    ...

    return default(T);
}

Попытка # 2 (используя отражение):

public static T Parse<T>(this NameValueCollection col, string key)
{
    string value = col[key];

    if (string.IsNullOrEmpty(value))
        return default(T);

    try
    {
        var parseMethod = typeof(T).GetMethod("Parse", new Type[] { typeof(string) });

        if (parseMethod == null)
            return default(T);

        // still boxing because invoke returns an object
        var parsedVal = parseMethod.Invoke(null, new object[] { value });
        return (T)parsedVal;
    }
    // No Proper Parse Method found
    catch(AmbiguousMatchException) 
    {
    }

    return default(T);
}
13
задан bendewey 23 December 2008 в 22:47
поделиться

3 ответа

Я думаю, что Вы по оценке влияния упаковки/распаковывания. Метод синтаксического анализа будет иметь намного большие издержки (строковый парсинг), затмевая упаковку наверху. Также весь, если операторы окажут большее влияние. Отражение оказывает самое большое влияние всех.

я был бы не хотеть видеть этот вид кода в производстве, поскольку существует более чистый способ сделать его. Основной проблемой, которую я имею с ним, является большое количество того, если операторы, необходимо будет покрыть все случаи и то, что кто-то мог передать любой старый тип ему.

то, Что я сделал бы, записать функцию синтаксического анализа для каждого типа, который я хочу проанализировать (т.е. ParseInt ()). Это более ясно, и это четко определено, что функция попытается сделать. Также с короткими статическими методами, компилятор, более вероятно, встроит их, сохраняя вызов функции.

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

8
ответ дан Robert Wagner 24 December 2008 в 08:47
поделиться
  • 1
    Обратите внимание, что с 2.9.0.1 (возможно, ранее) единственная причина, что Вы заканчиваете с именем поля, состоит в том, потому что Вы сослались на него в printName. Если никакие методы не ссылаются на ctor аргумент, он не долго генерирует поле. – Duncan McGregor 3 October 2011 в 06:18
public static T Parse<T>(this NameValueCollection col, string key)
{
  return (T)Convert.ChangeType(col[key], typeof(T));
}

я не совсем уверен в полях ChangeType или не (я предполагаю, что чтение документов сказало бы мне, но я тороплюсь прямо сейчас), но по крайней мере оно избавляется от всей той проверки типа. Упаковка наверху не очень высока, тем не менее, таким образом, я не волновался бы слишком много об этом. Если бы Вы волнуетесь по поводу непротиворечивости типа выполнения, я записал бы функцию как:

public static T Parse<T>(this NameValueCollection col, string key)
{
  T value;

  try
  {
    value = (T)Convert.ChangeType(col[key], typeof(T));
  }
  catch
  {
    value = default(T);
  }

  return value;
}

Этот способ, которым не будет бомбить функция, если значение не может быть преобразовано по любой причине. Это означает, конечно, что необходимо будет проверить возвращенное значение (который необходимо было бы сделать так или иначе, так как пользователь может отредактировать querystring).

34
ответ дан Robert C. Barth 24 December 2008 в 08:47
поделиться
  • 1
    Блестящий. Просто вид детали я был после. Я могу 100% понимать подход желания использовать время простоя в ярусе веб-узлов, чтобы сделать полнотекстовое индексирование и особенно не желание добавить другой компонент в инфраструктуру. Однако я могу также предвидеть много проблем с проявлением того подхода (масштабирование, зная, что инкрементно индексировать, диагностируя ищущие проблемы через ферму), но ни один, что непреодолимо. Учитывая, что Solr может (в теории) кластер, I' m собирающийся первоначально препятствовать вниз маршруту Solr, но мог бы угробить его в пользу маршрута яруса веб-узлов позже. – growse 30 June 2011 в 22:45
int value = int.Parse(Request.QueryString["RecordID"]);
0
ответ дан 1 December 2019 в 17:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: