Visual Studio 2022, Rider 2023.1, ChatGPT-4

Visual Studio 2022, Rider 2023.1, ChatGPT-4

21 апреля 2023 г.

Сегодня я собирался опубликовать твит вроде "Эй, коллеги-разработчики, используйте Rider/Resharper вместо старой доброй Visual Studio, потому что первый найдет и исправит для вас некоторые ошибки"; но потом я решил проверить, что последняя Visual Studio 2022 может сделать против Rider, и заодно вспомнил нашего нового друга ChatGPT...

Поэтому вместо короткого твита я хочу предложить вам небольшое соревнование между Visual Studio 2022, Rider 2023.1 и волшебным ChatGPT-4.

Что мы собираемся сделать сегодня, так это просмотреть программу на C# и попытаться обнаружить любые ошибки. Затем мы отправим код в наши любимые IDE (Rider и Visual Studio), чтобы посмотреть, смогут ли они выявить какие-либо проблемы с кодом.

Наконец, мы попросим ChatGPT проверить код и исправить все обнаруженные ошибки, если таковые имеются.

Давайте?

Требования

Допустим, мы хотим написать программу на C#, которая:

  1. Создает 10 пользователей со случайным рейтингом.

2. Находит пользователей с оценками от X до Y.

3. Если какие-либо пользователи найдены, то выведите:

  1. Количество найденных пользователей.

    2. Минимальный рейтинг среди найденных пользователей.

    3. Титул пользователя с минимальным рейтингом (титул основан на рейтинге).

Код

Вместо того, чтобы писать эту программу самостоятельно, мы попросили кого-то сделать это за нас (кого-то менее умного, чем современные системы искусственного интеллекта), и вот что мы получили:

var allUsers = GetAllUsers();
var foundUsers = FindUsersByRating(allUsers, 0, 60);

if (foundUsers.Any())
{
    var userWithMinRating = foundUsers.OrderBy(x => x.Rating).FirstOrDefault();
    PrintUsers(foundUsers);
    Console.WriteLine($"{foundUsers.Count()} user(s) found.");
    Console.WriteLine($"Min rating: {userWithMinRating.Rating}.");
    var title = GetTitleByRating(userWithMinRating.Rating);
    Console.WriteLine($"Title: {title.ToUpper()}");
}
else
{
    Console.WriteLine("No users found.");
}

IEnumerable<User> FindUsersByRating(IEnumerable<User> users, int minRating, int maxRating)
{
    return users.Where(x => x.Rating >= minRating && x.Rating <= maxRating);
}

IEnumerable<User> GetAllUsers()
{
    var randomizer = new Random();
    return Enumerable.Range(1, 10)
                     .Select(x => new User(x, randomizer.Next(0, 100)));
}

string GetTitleByRating(int rating)
{
    return rating switch
           {
               > 0 and < 30   => "Beginner",
               >= 30 and < 80 => "Advanced",
               >= 80          => "Expert",
               _              => null
           };
}

void PrintUsers(IEnumerable<User> users)
{
    foreach (var user in users)
    {
        Console.WriteLine(user.ToString());
    }
}

record User(int Id, int Rating);

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

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

Visual Studio 2022 Professional

Последней версией на момент написания статьи является .NET IDE от Microsoft.

Visual Studio 2022 code analyzer

(Остальной код не поместился на скриншоте, но это не имеет значения).

Как мы видим, Visual Studio не хочет нам ничего говорить (потому что не видит никаких проблем). Хорошо, давайте перейдем к следующему — Райдеру.

Райдер (версия 2023.1)

(Результаты аналогичны Visual Studio + Resharper)

Rider code analyzer

Хорошо, у нас тут кое-что есть!

Возможно множественное перечисление

Первое, на что Rider обращает наше внимание, — это предупреждение «Возможно множественное перечисление», которое в данном конкретном случае является не просто «возможным», а реальной проблемой:

Rider: possible multiple enumeration

Метод GetAllUsers возвращает "ленивый" IEnumerable<User> вместо реальных объектов, и в результате в строках 4, 6, 7 и 8 где мы перечислим этот IEnumerable<User>, будут созданы новые объекты User. Каждый раз.

Другими словами, когда мы запускаем нашу программу и точка выполнения достигает кода в строке 1, фактические пользователи не генерируются. То же самое относится и к строке 2.

И только когда мы достигнем строки 4 (foundUsers.Any()), фактические экземпляры User будут созданы, отфильтрованы, и оператор if проверит если у нас остались какие-либо предметы.

Пока все хорошо, но проблема в том, что в строке 6 метод FirstOrDefault() снова инициирует процесс создания и фильтрации новых элементов. Полностью новые предметы.

И то же самое происходит внутри метода PrintUsers, когда мы перебираем IEnumerable с помощью цикла foreach, и последнее перечисление происходит в строке 8. когда мы вызываем метод Count().

Таким образом, мы можем увидеть следующий вывод:

User { Id = 6, Rating = 46 }
User { Id = 8, Rating = 70 }
0 Users found.
Min rating: 51.
Title: EXPERT.

Какая ерунда! Мы видим 2 пользователей, но он говорит, что ни один не найден, затем печатает минимальный рейтинг, который не принадлежит ни одному из двух пользователей, которых мы видели всего двумя строками выше.

В довершение всего мы получаем звание ЭКСПЕРТ... Как мы уже говорили, все это происходит потому, что в строках 4, 6, 7 и 8 генерируются новые наборы пользователей.

Возможное исключение System.NullReferenceException

Другое справедливое замечание, сделанное Райдером, заключается в том, что userWithMinRating может быть нулевым, что может привести к срабатыванию NullReferenceException в строке 9:

Rider: Possible System.NullReferenceException

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

ChatGPT

Хорошо, теперь пришло время испытать чрезвычайно разрекламированный мощный искусственный интеллект, о котором все говорят в эти дни — ChatGPT-4🔥

Подсказка

При работе с ChatGPT (и другими языковыми моделями, такими как Bing Chat) подсказки имеют решающее значение, и, надеюсь, я не плохо справился. Итак, я объяснил суперразуму, что должна делать наша программа, и попросил его исправить любые ошибки, которые он может найти в коде:

ChatGPT-4 prompt

ChatGPT не заметил проблем, обнаруженных Rider, но обнаружил еще одну!

ChatGPT-4 fixes a bug in the C# program

Вау! Машина вычислила возможные значения свойства Rating класса User и заметила, что лучше включить 0 в диапазон значений, принадлежащих Начинающий титул!

Честно говоря, я не ожидал, что кто-то из конкурентов заметит эту проблему, и должен признать, что она впечатляет!

Выводы

Итак, какие выводы мы можем сделать из этого небольшого конкурса?

  1. Во-первых, если вы пишете код на C# за деньги, купите лицензию Rider или Resharper, чтобы использовать его с Visual Studio (если вы еще этого не сделали).

2. Visual Studio постоянно совершенствуется, но остается на несколько шагов позади Rider/Resharper. Он всегда отставал (начиная с первой версии Resharper) и, вероятно, будет в обозримом будущем.

3. ChatGPT-4 — зверь! Я экспериментировал с ним (не только с программированием и технологиями) с тех пор, как он стал доступен, и меня часто (хотя и не всегда) поражают результаты, которые превосходят мои ожидания.

4. Неясно, как быстро и каким образом эти ИИ-монстры интегрируются в нашу повседневную работу (в качестве вторых пилотов, интеллектуальных анализаторов кода, детекторов ошибок и т. д.), но ясно одно — за этим будущее.

Спасибо за чтение, используйте правильные инструменты разработки и до скорой встречи!

Здоровья!


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE