Немного кода, небольшой рефакторинг

    • .NET
    • C#
    • Twitter
    • Sample
    • Refactoring
  • modified:
  • reading: 3 minutes

Изучал тут как-то примеры книги Professional Twitter Development: With Examples in .NET 3.5, хотел разобраться как работает эта самая OAuth авторизация для твиттера. Раньше у меня на сайте было немного действий с твиттером, подгружались мой твитты, хранились, отображались, но потом твиттер что-то поменял в авторизации, вроде разрешил только OAuth, а в тот момент я что-то не шибко разобрался с этим OAuth, да и времени не было, хотя вроде еще тогда LinqToTwitter ее поддерживал (а я использовал именно эту библиотеку). В общем-то, просто в тот момент подумал, что тема OAuth авторизации интересна, и нужно бы посмотреть как она реализована в деталях попозже. Вот и набрел я тут недавно на книгу Professional Twitter Development: With Examples in .NET 3.5, точнее только на ее примеры, решил поковыряться. Код там был не из простых, и я просто тупо стал рефакторить его, чтобы разобрать что и как работает. Вот, например, одно из превращений, которое я уже правда публиковал в твиттере давно (и может быть вы уже видели):

Было:

public static string NormalizeRequestParameters
    (NameValueCollection parameters)
{    var sb = new StringBuilder();
     var list = new List<NameValuePair>();
    foreach (var name in parameters.AllKeys)
    {        var value = Uri.EscapeDataString(parameters[name]);
        var item = new NameValuePair { Name = name, Value = value };
         // Ensure duplicates are not included
        if (list.Contains(item))
        {            throw new ArgumentException(
                "Cannot add duplicate parameters");
        }
 
        list.Add(item);
    }
 
    list.Sort((left, right) =>
    {        if (left.Name.Equals(right.Name))
        {            return left.Value.CompareTo(right.Value);
        }
         return left.Name.CompareTo(right.Name);
    });
     foreach (var item in list)
    {        sb.Append(item.Name + "=" + item.Value);
        if (list.IndexOf(item) < list.Count - 1)
        {            sb.Append("&");
        }
    }
     return sb.ToString();
}

Стало:

public string NormalizeRequestParameters
    (NameValueCollection collection)
{    IEnumerable<string> parameters = collection.AllKeys.OrderBy(x => x)
        .Select(x => string.Format("{0}={1}", x, Uri.EscapeDataString(collection[x])));
     return String.Join("&", parameters);
}

На первый взгляд у меня опущено два момента: а) не бросается исключение б) сортировка другая, там order by ключ, значение, а у меня просто order by ключ.

На самом деле тут просто логика самого класса NameValueCollection, если вы инициализируете его так:

new NameValueCollection { { "test1", "value1" }, { "test1", "value2" }};

то он превратится в

new NameValueCollection { { "test1", "value1&value2" }};

А следовательно проверки и бросания исключения не нужны, да и в OrderBy нет смысла добавлять вторым параметром значение, так как там не может повториться ключ.

В общем, я только хотел сказать, что C# 4 отличный язык, позволяет делать действительно очень читабельным наш код. И это не значит, что я хочу принизить книгу, думаю она отлична и полезна для тех, кто хочет разработать свой твиттер клиент, или проинтегрировать свое приложение с твиттером, а так все пишут плохой код, а кто считает что нет, тот пишет код еще хуже ;)

See Also