Блог пользователя AlexSkidanov

Автор AlexSkidanov, 14 лет назад, По-русски
Перечитав все, чем я был недоволен С# тут я выяснил, что кроме отсутствия SortedSet, который был объявлен только в .NET 4.0, C# тут абсолютно perfect. CBR7 это подтвердил.

Характерно, что после всего четырех месяцев работы на C# я уже чуствую неудобство работы на других языках. Как однажды сказал один крутой (для меня :о)) ACM-щик, "я пишу не на С++, я пишу на STL". Вот также и тут, я пишу не на C#, я пишу на Linq :о) Потому что без Linq С# это таже самая Java, только без BigInteger (BigInteger появился тоже только в .NET 4.0). И поэтому я должен сказать спасибо Михаилу,  так как реально сегодня нормальной версии C# с Linq почти нигде на регулярных соревнованиях нет (и на TC и у снарка C# cтарый, без Linq).

Теперь немного рекламы. Почему же я тащусь от C#.
1. Мне не надо писать тип объекта, который я создаю. На С++ это не проблема, но на Java в принципе она проявляется, хотя, конечно, Java программисты на нее не обращают внимания. Допустим,
List<int> q = new List<int>( );
Тупо - я пишу тип дважды. Конечно, это плохой пример - любая интегрированная среда сразу после набора слова new предложит по Enter или типа того тим переменной, и реально человек наберет List<int> только однажны. Но что, если мне надо
(тип переменной) q = SomeClass.SomeMethod( ).SomeOtherMethod( )...
Я не хочу задумываться, какого типа будет возвращаемое значение этого SomeOtherMethod, я могу вообще теоретически не знать до набора этой строки, какой будет тип. В C# на этот случай есть ключевое слово var.
var lst = new List<int>( );
var q = SomeClass.SomeMethod( ).SomeOtherMethod( )...
Всегда, когда компилятор может сам понять тип переменной (то есть грубо говоря всегда, когда вы ее сразу инициализируете), ее тип можно не указывать лапками.

2. Мне не надо создавать типы данных под все подряд
Я хочу создать переменную, с тремя полями: id, x и y. Когда параметров два, C++ шники всегда юзают pair - это круто, в Java даже для двух надо делать отдельный тип. В любом случае, если полей три, то на C++ тоже надо создавать новый тип. На C# все проще
var q = new { id = 4, x = 4, name = 5 };
И все, мне не надо проматывать код чтобы создать новый класс. Но вы не прочуствуете всей мощи этого, пока не прочитаете пункт 3.

3. А теперь, когда у меня есть непонятные типы, я хочу их сортировать. Я не хочу переопределять операторы, мне лень это делать :о Приходит на помощь Linq. Допустим, что qs - это массив чего-то типа q, который я создал на прошлом шагу
var qs_sorted = ( from q in qs orderby q.id select q );
И все. Никаких переопределений операторов :о)
Я хочу отфильтровать его, оставив только те, где x < 10?
var qs_filtered = ( from q in qs where q.x < 10 orderby q.id select q );
Я хочу при этом получить только x и y, и откинуть id?
var qs_xy = ( from q in qs where q.x < 10 orderby q.id let x = q.x let y = q.y select new { x, y } );

4. Это уже не про язык или платформу, а про среду. Почему многие любят C++? Потому что там можно записать макросы для циклов. На топкодере почти у всех есть макрос для фора. Потому что в 90% случаев фор делается по проторенной дорожке for( i = 0; i < n; ++ i ) или for( i = n - 1; i >= 0; -- i ). Меняется только i и n. Разумеется, у всех набита рука вбивать это дело, но хочется все-таки вбивать только i и n. Поэтому макросы типа FOR(i,n) или rep(i,n) или типа того очень популярны. В Visual Studio мы делаем так. Пишем for, дважды бьем кнопку Tab, нам сразу разворачивается вся конструкция и курсор установлен на то место, где мы хотим вбить название переменной. И название сразу i. Меняем название на j, все три вхождения i меняются на j. Жмем tab, попадаем на length, меняем length на то, что нам надо, скажем n, жмем Enter и попадаем в тело цикла. Надо цикл с конца - делаем все тоже самое, написав в начале forr вместо for. Эта фишка называется Code Snippets, и она реально крутая. Не удивлюсь, если в других средах разработки она тоже есть.

5. Добавим к этому перегрузку операторов, которая все-таки есть, параметры по умолчанию для методов, причем более мощные, чем в C++ - грубо говоря вы не обязаны предоставлять параметры для функции по порядку, вы можете сделать 100 параметров, все с значениями по умолчанию, а потом вызвать эту функцию, передав только 18-ый и 99-ый. В С++ вы обязаны передавать параметры начиная с начала и поюзать значения по умолчанию только для подрядидущих с конца параметров.
Но видимо это все уже олимпиаднику не надо :о)

С учетом SortedSet и BigInteger в .NET4.0 C# в принципе будет иметь все, что надо в стандартной библиотеке. Сегодня приходится использовать SortedDictionary вместо SortedSet, что немного тупо :о( И для длинной арифметики приходится писать на Java не редко.
Кстати, в .NET 4.0 для BigInteger перегружены все опреаторы, и с ним можно тискаться как с любыми другими типами :о) Это вам не громоздкие конструкции на Java писать с тонной вызовов методов :о
Теги c#
  • Проголосовать: нравится
  • +13
  • Проголосовать: не нравится

14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
В с0x++ (а так же в MSVS2010) первый пункт реализован (там это называется auto)
14 лет назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится
Ещё бы всё это добро на ТопКодере появилось. Тогда я бы на C# перешёл.
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
А на ACM-ICPC С# раньше был?
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Никогда не был, и я готов биться об заклад, что никогда не будет.
    ACM ICPC вообще отвратительно организованное соревнование.
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Это почему?
    • 14 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится
      Хм, не знаю, что там такого отвратительного... Net отсутствует, потому что проводит чемпионат IBM, и им шарп включать как-то не к лицу. Они ведь поддерживают Open Source, в частности Linux, Eclipse. Не покупать же им кучу Windows и VS лицензий у своего конкурента, чтобы добавить проприетарную платформу. А Mono.. ну, может когда-нибудь его добавят, хотя вряд ли, не видно причин для этого.
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Ну видимо это первая проблема: почему чемпионат мира привязан к платформе? Я хочу писать под Windows, а не под Linux.

        Про организацию - это я просто не касаемо C# сказал. IBM обнищал, и последний ЧМ был просто отвратительный. Вот если бы вы были на ЧМ в 2008 году, когда все проходило в нереально живописном месте, и, что очень важно, все проходило в одном месте, и если вы устали от идиотизма на открытии, когда куча нафиг никому не интересных официальных лиц заполняет полный граф поздравления друг друга, пучера и участников, то вы можете пойти в свой номер - потому что все в отеле.
        И сравнить это все с финалом 2010, когда все проходило на помойке, открытие и все остальное было в 40 минутах езды на автобусе от отеля, без интернета, поэтому когда через 10 минут после начала открытия вы поняли, что ДОМ-2 - это не самое долбануца нудное шоу, но деваться вам некуда - вот тут вы прозреваете с организации :о)

        А еще кстати постоянный эффект ACM ICPC, кто был - тот знает. На закрытии, которое длится допустим час, в течение 40 минут поздравляют всех организаторов, IBM, UPE, волонтеров, их всех вызывают на сцену, называют по именам, всем в зале на это нахрен посрать.
        А потом в последние 20 минут поздравляют команды. Их вызывают на одну минуту на сцену (а как иначе за 20 минут поздравить 12 команд?) и (!!!) их НЕ называют по именам. Это вообще писец.
        • 14 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          На финале награждаются команды, а не отдельные их члены. Пучер с названиями универов-то парится, а если еще имена участников называть - он вообще язык сломает. А потом еще обиды начнутся - он мою фамилию извратил, ах какой поганый ICPC.
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            А зачем тогда остальных (волонтеров, организаторов и т.д.) поименно поздравляют?
            • 14 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится
              Потому что Пучер может натренироваться говорить их имена заранее и им обидно не будет :)
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            Я четыре года готовился к соревнованию, мне не очень принцпиально, что именно послужило причиной на награждении больше внимания уделить волонтерам, чем мне. Для меня важен сам факт того, что это так, и это не нормально :о)
            А уж попросить команды "произнести" их ВУЗ при регистрации казалось бы вообще очевидное действие.
            Кстати на TopCoder Open вообще всех называют по именам (или по крайней мере называли когда я там был), и ничего, справляются.
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Параметры по умолчанию и именованные, к сожалению, лишь в C#4.0. 

var qs_xy = ( from q in qs where q.x < 10 orderby q.id let x = q.x let y = q.y select new { x, y } );

стоит писать как:

var qs_xy =  from q in qs 

                    where q.x < 10

                    orderby q.id

                    let x = q.x let y = q.y

                    select new { x, y };

Это общепринятая практика и значительно повышает читабельность кода.

  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Классно, почти чистый sql. Это и есть linq? А асимптотика сортировки изменяется при использовании linq (и какая она в данном случае)?
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Это только малая часть LINQ - LINQ to Object. 

      Асимптотика не изменяется, та же, что и в Array.Sort. Какая? Нужно смотреть коды, коих у меня на машине нет. Должно быть O(n*log(n)).

      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        На самом деле Linq to Object, Linq to SQL или что-то еще - принципиальной разницы нет, синтаксис-то один. В этом и вся прелесть, что можно вообще забить на то, что именно является твоим источником данных.

        Разве что JOIN для Linq to Object работает за квадрат, и это расстраивает...
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    На олимпиадке мне не слабо накласть на читаемость моего кода :о)
    Мне надо чтобы мой код влазил на экран, чтобы я в нем ориентировался. Я не хочу парсить вход в пять строк, допустим, мне нужен Linq как раз для того, чтобы сделать это в одну :о)
14 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится
Я использую Python в течение 3 месяцев just for fun, и теперь мне понятно, чего мне так не хватало в других языках: краткости и выразительности!

Позволю себе написать, как можно решить задачи из пункта 3 и кое-что другое на питоне (по-моему, сходство подходов очевидно).

---------------------------------------------------------------
q1 = (4, 4, 'mike')
q2 = (50, 50, 'petr')
q3 = (3, 3, 'alex')

qs = [q1, q2, q3] # create a list of tuples
print qs

def by_id (q):
    id, x, name = q # unpacking a tuple - for clearity
    return id
    #return q[0] - the same
   
qs_sorted = sorted (qs, key = by_id)
print qs_sorted

# the same using lambda
qs_sorted = sorted (qs, key = lambda q: q[0])
print qs_sorted

qs_sorted_reversed = sorted (qs, key = lambda q: q[0], reverse = True)
print qs_sorted_reversed

qs_filtered = [q for q in qs if q[1] < 10]
print qs_filtered

qs_sorted_filtered = [q for q in sorted (qs, key = lambda q: q[0]) if q[1] < 10]
print qs_sorted_filtered

qs_xy = [(q[0], q[1]) for q in qs if q[1] < 10]
print qs_xy

qs_id_squared_x_cubed = [(q[0]**2, q[1]**3, q[2]) for q in qs]
print qs_id_squared_x_cubed
---------------------------------------------------------------
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
А можно код, как будет на Ruby?
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Сразу скажу, что я не сильный шаман в ruby... Такой же результат можно получить, например, с помощью такого кода:
    q1 = [4, 4, 'mike']
    q2 = [50, 50, 'petr']
    q3 = [3, 3, 'alex']

    qs = [q1, q2, q3] 
    p qs

    qs_sorted = qs.sort_by {|x| x[0]}
    p qs_sorted

    qs_sorted_reversed = qs.sort_by {|x| x[0]}.reverse
    p qs_sorted_reversed

    qs_filtered = qs.find_all {|x| x[1] < 10}
    p qs_filtered

    qs_sorted_filtered = qs.sort_by {|x| x[0]}.find_all {|x| x[1] < 10}
    p qs_sorted_filtered

    qs_xy = qs.find_all {|x| x[1] < 10}.map {|x| [x[0], x[1]]}
    p qs_xy

    qs_id_squared_x_cubed = qs.map {|x| [x[0]**2, x[1]**3, x[2]]}
    p qs_id_squared_x_cubed
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Дописал в первый пост:

Это уже не про язык или платформу, а про среду. Почему многие любят C++? Потому что там можно записать макросы для циклов. На топкодере почти у всех есть макрос для фора. Потому что в 90% случаев фор делается по проторенной дорожке for( i = 0; i < n; ++ i ) или for( i = n - 1; i >= 0; -- i ). Меняется только i и n. Разумеется, у всех набита рука вбивать это дело, но хочется все-таки вбивать только i и n. Поэтому макросы типа FOR(i,n) или rep(i,n) или типа того очень популярны. В Visual Studio, кодяча на C#, мы делаем так. Пишем for, дважды бьем кнопку Tab, нам сразу разворачивается вся конструкция и курсор установлен на то место, где мы хотим вбить название переменной. И название сразу i. Меняем название на j, все три вхождения i меняются на j. Жмем tab, попадаем на length, меняем length на то, что нам надо, скажем n, жмем Enter и попадаем в тело цикла. Надо цикл с конца - делаем все тоже самое, написав в начале forr вместо for. То есть мы нажали:
for \t \t j \t n \n
Не так плохо, не больше чем набирать rep( i, n )...
 Эта фишка называется Code Snippets, и она реально крутая. Не удивлюсь, если в других средах разработки она тоже есть.
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    В eclipse подобное тоже есть (Java), правда я этим как-то не пользуюсь. Привыкнуть надо просто. Пока не привыкнул - такое только замедляет. :)
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Есть в eclipse, netbeans, и вроде бы даже komodo edit 
13 лет назад, # |
Rev. 12   Проголосовать: нравится +1 Проголосовать: не нравится
Да бывает начинаеш писать алго и понимаеш что вот счас надо создать сет...
Знаю два судьи на которых есть .NET 4.0 это Timus и E-Olimp. Топкодер третий у кого компилятор Микрософта, но почему до сих пор у них 2.0 не понятно :[
В Виннице спрашивал Поучера когда на ACM будет шарп - уклонился.
Тоже познавательно: http://www.slideshare.net/jeffz/why-java-sucks-and-c-rocks-final
  • 13 лет назад, # ^ |
      Проголосовать: нравится +2 Проголосовать: не нравится
    Не познавательно - визуализированая паника безмозглого фанбоя 
    • 13 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится
      Метко обозвано. Впрочем, думаю 50% java-разработчиков с нетерпением ждут наступления конца 2012 года к которому обещается выход Java 8 с closures. А то за 5 лет простоя на 6-й версии она изрядно поотстала и троллинг шарпистов выглядит всё более и более обидно... Впрочем, фреймворки-то развивались всё равно, так что далеко не всё потеряно... ;-)
      • 13 лет назад, # ^ |
          Проголосовать: нравится -7 Проголосовать: не нравится
        Классно, что есть конкуренция.
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Я точно не уверен, но о конкуренции сложно говорить по-моему... На C# (т.е. .NET) и на Java на текущий момент вроде бы в основном пишут приложения довольно различающегося назначения и характера.

          Поправьте, если ошибаюсь... Я так понимаю что Microsoft создаёт возможности для разработки ПО уровня предприятия на C#, но этим пока довольно мало кто пользуется в отличие от J2EE. С другой стороны настольных приложений на Java по-моему значительно меньше рожается.

          Кстати, просветите, можно ли enterprise-разработку на Mono с успехом вести и если да, насколько это популярно?
          • 13 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            Наша контора, тогда, видимо, в меньшинстве - мы пишем на Java SE. В Петербурге, кстати
13 лет назад, # |
  Проголосовать: нравится -8 Проголосовать: не нравится
С# и Python я бы не стал сравнивать, один язык интерпретируемый, другой нет. C# строго типизированный, и быстрее, но питон красивее, проще, но медленнее.
Но скажу что Python и C# это да, два языка которые "just for fun" или серьёзно стоит глянуть :)
Ну а потом глянуть Ruby, и Haskell что бы башню свернуло :D

Другой вопрос, BigInteger в C# мне понравился, но он идёт с Net 4.0 и его мне нужно было добавить в ссылки его библиотеку Numeric, что бы всё заработало. Так вот на Codeforces Numeric пашет? :)
И все остальные рюшечки: делигаты, лямбда выражения, и Linq? :o)
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Хотя бы второй абзац прочитал перед комментированием =) Там про Linq точно написано.
    • 13 лет назад, # ^ |
        Проголосовать: нравится -11 Проголосовать: не нравится
      Да пофиг, жалко BigInteger не идёт в стандартной комплектации, а нужно брать System.Numeric из Net 4 :(
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Делегаты, лямбда выражения и Linq работают.
    Не разбираюсь в версиях Mono но тут что-то вроде .NET 3.5 .
13 лет назад, # |
  Проголосовать: нравится -7 Проголосовать: не нравится
А есть ли возможность сюда поставить .NET 4.0? :o)
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Для первого пункта в джаве пишу сначала длинное выражение, потом с помощью сочетания клавиш выделяю в переменную. Тип среда подставляет сама.
13 лет назад, # |
  Проголосовать: нравится -7 Проголосовать: не нравится
Ребята неадекватны, за что минусуют.


13 лет назад, # |
  Проголосовать: нравится +2 Проголосовать: не нравится

Шарп действительно мощная штука, жаль, что не поддерживается много где. Вообще полноценный шарп - это шарп от microsoft, а значит дотнет, а значит windows, который стоит денег, так что на соревнованиях этого языка ждать не стоит.

По поводу linq - сначала использовал такой же синтаксис, потом перешел на extensions функции. Как-то строже смотрится. Кстати extensions тоже классная штука, правда в олимпиадном программировании, наверное, нет смысла ее применять.

Code snippets для олимпиадника просто открытие, я считаю. Минус дефайнов в том, что не все их любят и в команде кто-то использует, кто-то нет, а главное, нередко приходится менять тот же forn(i, n) на что-то вроде for(int i = 1; i <= n; ++i). Code snippets не скрывают код, а делают его автоматическую подстановку, которую можно настроить и изменить эту часть кода в дальнейшем.

А автоматическое определение типа с var и анонимные типы не требуют комментариев, удобство очевидно. Анонимные типы, кстати, это все еще строгая типизация, а значит IntelliSense никуда не девается.

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

  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    жаль, что не поддерживается много где ... а значит windows, который стоит денег

    Проблема даже не в том, что виндовс стоит денег. Не такие это большие деньги. Проблема именно в том что в то время как все потихоньку приходят к кроссплатформенной разработке на скриптовых языках, Java или QT, микрософт упорно пытается действовать наоборот - заставить весь мир использовать собственные решения. В принципе это не было бы так сложно, если бы решения микрософта были бесспорны и гениальны.

    Я не говорю что различные линуксы бесспорны и гениальны - но по крайней мере чтобы развернуть ресурс сделанный на PHP, J2EE и т.п. человек может выбрать практически любой дистрибутив виндов или линуксов выпущенный за последние лет пять, либо взять подходящий сервер/хостинг. С ASP .NET ему нужен конкретный сервер с конкретной ОС. И не дай Бог проснуться утром и узнать что эта версия ОС снята с поддержки, и надо всем срочно перейти на Windows Ultra Ultimate Server.

    Вот если б Микрософт активно поддержал проект Mono, я думаю это здорово помогло бы развитию в народе любви к C#.
    • 13 лет назад, # ^ |
        Проголосовать: нравится +3 Проголосовать: не нравится
      >проснуться утром и узнать что эта версия ОС снята с поддержки

      Вообще-то для каждой версии винды заранее известна дата окончания поддержки. Причем намного заранее.

      >С ASP .NET ему нужен конкретный сервер с конкретной ОС.

      Не вижу никакой проблемы. Хостингов с ASP.NET полно и стоят они примерно также как и остальные.

    • 13 лет назад, # ^ |
        Проголосовать: нравится +2 Проголосовать: не нравится

      Холивар детектед?

      Мне кажется, Вы немного отошли от контекста. Лично мне тоже во многом не нравится стратегия microsoft, но я думаю, что там работают умные люди, и они знают, что делают. И, думаю, причина как раз в деньгах =)

      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Звучит как, "давайте юзать микрософт, ведь они делают все это, чтобы заработать деньги, поможем им заработать". 



        PS: не имею никакого мнения о C# ибо не сталкивался
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Почему CodeSnippets все ставят, как плюс шарпа? Сниппеты же можно даже в вим поставить и с ним работать так же удобно. То есть сниппеты можно хоть на какой язык настроить.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Я так понимаю, это зависит от среды разработки? Ну в VS я не знаю как это в С++ прикрутить...
13 лет назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится
Язык вообще отличный. Но вот недавно столкнулся с интересной проблемкой. Если выделить большой кусок памяти, то любимый всеми сборщик её не вычистит. Точнее вычистит, но не дефрагметирует. И, Вот проблемка. На сервере убежит память. Никто не сталкивался?
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Сталкивались многие. Прочитайте первые 3-4 ссылки которые выдает гугл по "loh fragmentation".