今天我本打算发一条 "嘿,各位开发者,请使用Rider/Resharper而不是老式的Visual Studio,因为前者会帮你找到并修复一些错误 "的推文,但后来我决定检查一下最新的Visual Studio 2022对Rider能做什么,而且在检查时,我想起了我们的新朋友ChatGPT。因此,我想在Visual Studio 2022、Rider 2023.1和神奇的ChatGPT-4之间进行一次小竞赛,而不是发一条短推文。
我们今天要做的是审查一个C#程序并尝试发现任何错误。然后,我们将把代码送入我们最喜欢的IDE(Rider和Visual Studio),看看它们是否能突出任何代码问题。最后,我们将要求ChatGPT审查代码并修复所有发现的错误(如果有)。
开始吧?
要求
假设我们想写一个C#程序:
-
生成10个具有随机评分的用户。
-
找出评分在X和Y之间的用户。
-
如果找到任何用户,则打印:
代码
我们没有自己写这个程序,而是请别人帮我们写(比现代人工智能系统更不聪明的人),结果是这样的:
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专业版
在撰写本文时,是微软最新的.NET IDE。
(其他的代码不适合放在截图上,但这并不重要)。
我们可以看到,Visual Studio不想告诉我们任何东西(因为它没有看到任何问题)。好了,让我们继续下一个Rider。
Rider(v 2023.1)
(与Visual Studio + Resharper的结果相似)
好的,我们在这里发现了一些东西!
可能的多重枚举
Rider提请我们注意的第一件事是 "可能的多重枚举 "警告,在这个特殊的案例中,这不仅仅是 "可能",而是一个实际的问题:
GetAllUsers
方法返回一个 "懒惰的 "IEnumerable<User>
,而不是实际的对象,因此,在第4、6、7和8行,在我们枚举这个IEnumerable<User>
,新的User
对象将被创建。每一次都是如此。换句话说,当我们运行我们的程序,执行点到达第1行的代码时,将不会产生实际的用户。第2行的情况也是如此。而只有当我们到达第4行(foundUsers.Any()
)时,实际的User
实例将被创建,被过滤,if
语句将检查我们是否还有任何项目。
到目前为止,情况还不错,但问题是,在第6行,FirstOrDefault()
方法将重新启动创建和过滤新项目的过程。完全是新的项目。而当我们用foreach
循环遍历IEnumerable
的时候,同样的事情也发生在PrintUsers
方法里面,最后一次枚举发生在第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"。
Rider提出的另一个公平的观点是,userWithMinRating
可以是空的,这可能导致在第9行触发一个NullReferenceException
:
虽然这看起来是一个简单而容易发现的错误,但它是生产代码中最常见的异常之一。
ChatGPT
好了,现在是时候测试一下最近大家都在谈论的被炒得沸沸扬扬的人工智能强国--ChatGPT-4🔥。
提示
在处理ChatGPT(和其他语言模型如Bing Chat)时,提示是至关重要的,希望我在这里没有做得不好。所以,我向超级大脑解释了我们的程序应该做什么,并要求它修复它能在代码中发现的任何错误:
ChatGPT没有注意到Rider检测到的问题,但它又发现了另一个问题!
哇!机器找出了User
类的Rating
属性的可能值,并注意到在属于Beginner
标题的值的范围内最好包括0!说实话,我没有想到任何一个竞争对手会注意到这个问题,我必须承认,这令人印象深刻!"!
结论
那么,我们能从这次小竞赛中得出什么结论呢?
-
首先,如果你写C#代码是为了赚钱,那么就去购买Rider或Resharper的授权,以便与Visual Studio一起使用(如果你还没有这样做的话)。
-
Visual Studio正在不断改进,但它仍然落后于Rider/Resharper几步。它一直处于落后状态(从Resharper的第一个版本开始),而且在可预见的将来可能还会如此。
-
ChatGPT-4是一个野兽!我一直在使用它!自从它问世以来,我一直在玩它(不仅是编码和技术),而且我经常(尽管不总是)对结果感到惊讶,它超过了我的预期。现在还不确定这些人工智能怪物会以多快的速度和方式融入我们的日常工作(作为副驾驶、智能代码分析器、错误检测器等),但有一点是明确的,这就是未来。
谢谢你的阅读,请使用正确的开发工具,我们很快就会再见面!
干杯!