Молодец, хорошее исследование на тему boxing/unboxing. Насчет R# совет: его warning на redundant .ToString() call можно заменить на hint или suggestion. И видно, и глаз радуется зеленому индикатору.
Не, ну я понимаю, безударные гласные, одна/две буквы «н», даже ошибку в тся/ться я могу понять. Но откуда у людей в голове берется этот «ВЫЙГРЫШ» я понять не смогу никогда.
Вообще, ToString() про перегруженых операциях лучще юзать почаще, т.к. его отсутствие временами порождает неочевидные(по крайней мере в первый раз, когда с этим сталкиваешься) неявные преобразования. Из наиболее известного:
С моими лекциями и присутствием на них было всё в порядке. Спасибо, что поинтересовались.
Однако хотелось бы подчеркнуть что мой комментарий был реакцией на вполне конкретный пример. Чар и инт, собственно, там одно и то же. Смысл в написании код и понимании как он будет читаться (машиной). Я думаю ни для кого не секрет что у каждого выражения будет своё значение: 1 + «2» + 3 + 4, 1 + 2 + «3» + 4, 1 + 2 + 3 + «4», 1 + 2 + 3 + 4.
П.С.: магии нет — есть разные языки и их ревизии со своим отношением к explicit/implicit.
Статья хорошая. Главный вывод из нее, как мне кажется — «используйте ToString() в тех случаях, когда это выгодно». А во всех остальных случаях я предпочту более компактный код.
главное ведь не то, насколько он компактный (иначе вы б не использовали «многословный» С#, а предпочли бы, к примеру, APL/J/K). главное насколько код удобочитаемый. для меня someInt + someString не настолько понятный код, как someInt.ToString() + someString (но это субъективно, конечно). а если, к тому же, более понятный код оказывается более эфективным, то я просто не вижу причин его использовать… (и только не нужно говорить, что набирать меньше. большинство проггеров на .ToString() тратят меньше секунды времени).
Всё относительно. Если есть узкое место, то его нужно оптимизировать, а добавлять во всех случаях, а не только для структур, вызов ToString() — это уже преждевременная оптимизация.
P.S. Кстати интересно, Resharper выдаёт предупреждение на код, находящийся в цикле, или на единичный вызов, или и там и там?
Понятно, что настраивается. Просто интересно, если поместить тот же вызов в цикл, Resharper по умолчанию продолжит выдавать предупреждение или сочтёт что в цикле лучше оставить ToString()?
а как тот факт, что вызов в цикле или нет может влиять на «суждения» решарпера? если даже это единичный вызов в методе, то сам метод может вызываться в цикле.
А при чем тут обида? Не нужно становиться заложником инструмента, вот и все. Нужно разбираться досконально в тех советах, что он предлагает. Решать, где совет обоснован, а где — не очень. Статья и призвана разобраться в одном из этих вопросов.
Использование ToSting() в скором времени приводит к тому, что он начинает плодиться по всему коду, и его вызывают просто на всякий случай, и это приводит к тому, что выигрыш, полученный в одном методе, тратится на 10 излишних вызовов в других (по крайней мере, в 80% код ревью, в которых приходилось участвовать, то было так).
Использование конкатенации (+ в С# или string.Concat) строк метод, имеющий право на жизнь, но я бы рекомендовал не использовать его как «волшебную палочку». Если реально код дожен быть более производительным — используйте StringBuilder. В той же книге Рихтера объясняется почему (вкратце, потому что этот класс по другому работает с массивом char). Например, немного модифицированный пример (чтобы строка постоянно росла).
var time = Stopwatch.StartNew();
string s = «habrahabr»;
for (int i = 0; i < 100000; i++)
{
s += i.ToString();
}
Console.WriteLine(time.Elapsed.ToString());
time = Stopwatch.StartNew();
StringBuilder sb = new StringBuilder();
sb.AppendFormat(«habrahabr»);
for (int i = 0; i < 100000; i++)
{
sb.Append(i);
}
Console.WriteLine(time.Elapsed.ToString());
дал следующие результаты:
00:01:10.4000846
00:00:00.0314729
Если не касаться производительности, то использование конкатенации здорово усложняет жизнь при локализации приложений.
ЗЫ. С темой упаковки/распаковки — поддерживаю автора на все сто
где-то читал конкатенация через +, дает выигрыш в сравнении со StringBuilder, если количество слагаемых не привышает 8, если элементов больше, то StringBuilder здесь лидер.
Это точно, отладка тоже очень важный фактор… учитывая тот фактор, что заметная разнича только на миллионах и только с большими структурами, то лучше иметь красивый код в случае единичного использования или не очень большом цикле.
Автору спасибо, интересно было узнать :)
Сначала не понял — R# это вроде как метапрограммистский проект на RSDN. Что касается решарпера, то да, у него есть ряд таких «коррекций», которые являются ошибочными. Например удаление пустого статического дефолтного конструктора.
Спасибо за статью, но…
Раньше тоже страдал такими вот «выигрышами» (да и сейчас нередко)… Но после плотной работы с оптимизацие производительности, понял, что такие выигрышы ничего не стоят. Даже самый «толстый» вызов стоит микросекунды, так что бороться здесь просто не за что. А если они становятся проблемой — значит проблема где-то выше.
Прав ли R#: call to .ToString() is redundant?