引言:关于“已死”的C#的传说
您可能听说过,C#是一种用于“企业级”的语言,一切都枯燥、缓慢,并且覆盖着一层企业官僚主义。但事实是,如今的C#开发人员是IT领域的全能战士。他用ASP.NET Core编写快速的微服务,通过Entity Framework优化数据库查询,有时甚至用ML.NET嵌入机器学习。
在本文中,我不会讲述抽象的理论。我们将经历一家真实公司中C#程序员的典型工作日:从早上的咖啡到将代码推送到生产环境。您将看到代码示例、工具以及能节省数小时工作时间的技巧。
08:30 — 早晨:咖啡、邮件和任务板
一天不是从代码开始的,而是从了解上下文开始。我首先打开Slack和Jira。在典型的团队中,有早上的站会(daily stand-up)。在会上,我们回答三个问题:
- 昨天做了什么?
- 今天打算做什么?
- 有什么阻碍吗?
站会后,快速浏览同事的拉取请求。C#的代码审查不仅仅是“打个勾”。这里重要的是检查是否有内存泄漏(特别是使用IDisposable时),以及是否正确使用了async/await。
实际案例:异步方法的代码审查
// 糟糕:在异步方法内部进行阻塞调用public async Task<User> GetUserAsync(int id){ var user = _context.Users.Find(id); // .Find — 同步的! return await Task.FromResult(user); // 无用的包装}
// 良好:完全异步public async Task<User> GetUserAsync(int id){ return await _context.Users.FindAsync(id); // 真正的异步}这种小细节可能会在负载下扼杀性能。因此,C#程序员必须每一步都关注异步性。
10:00 — 处理任务:编写新的API端点
今天的产品待办事项中有一个任务:“添加按价格筛选商品的功能”。这是.NET开发人员的典型故事。我在Visual Studio 2022中使用ReSharper(是的,它有点慢,但没有它就像没有双手一样)。
步骤1:模型和DTO
首先定义数据模型。假设我们有Entity Framework Core和PostgreSQL数据库。
public class Product{ public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Category { get; set; }}
public class ProductFilterDto{ public decimal? MinPrice { get; set; } public decimal? MaxPrice { get; set; } public string? Category { get; set; }}步骤2:使用IQueryable的仓储
主要技巧是不要将所有数据加载到内存中,而是使用IQueryable。这允许在数据库端构建SQL查询。
public async Task<List<Product>> GetFilteredProductsAsync(ProductFilterDto filter){ var query = _context.Products.AsQueryable();
if (filter.MinPrice.HasValue) query = query.Where(p => p.Price >= filter.MinPrice.Value);
if (filter.MaxPrice.HasValue) query = query.Where(p => p.Price <= filter.MaxPrice.Value);
if (!string.IsNullOrEmpty(filter.Category)) query = query.Where(p => p.Category == filter.Category);
return await query.ToListAsync();}请注意:我们直到最后才调用.ToList()。这是任何C#开发人员的基本但至关重要的模式。
步骤3:ASP.NET Core控制器
[ApiController][Route("api/[controller]")]public class ProductsController : ControllerBase{ private readonly IProductRepository _repo;
public ProductsController(IProductRepository repo) =&g