C#代码的七宗罪:老司机带你清除这些技术债(附改造方案)

作者:微信公众号:【架构师老卢】
6-7 8:56
15

前几天我review了一个代码库——这是个从.NET Framework 4.5时代遗留下来的企业级应用。虽然保留了分层架构,但业务逻辑和UI事件纠缠不清,几乎每行代码都在呐喊:"我是赶工写出来的!"

这个下午给了我当头一棒。从业多年,我见过太多"杰作":臃肿的控制器方法、深不见底的if-else嵌套、还有那些捕获异常后什么都不处理的"天才"写法。

下面是我用血泪总结的7个必须从C#代码中清除的坏习惯,想要写出比你的早餐咖啡更持久的软件?那就接着看下去。

1. 魔法字符串和数字

每次看到这种代码,我都想收一块钱...

if (user.Role == "Admin")
{
    ApplyDiscount(0.2);
}

硬编码的值看似方便,但这些"魔法值"终将成为地雷。一个小拼写错误可能引发需要数天调试的bug。

正确做法:

public static class Roles
{
    public const string Admin = "Admin";
}

public static class Discounts
{
    public const double AdminDiscount = 0.2;
}

if (user.Role == Roles.Admin)
{
    ApplyDiscount(Discounts.AdminDiscount);
}

使用常量、枚举或配置文件。这是代码自文档化的关键,也能避免那些沉默的运行时杀手。

2. 过度注释

没错,你没听错。太多开发者写了长篇大论的注释来解释下一行代码要做什么。

// 检查用户是否活跃
if (user.IsActive) { }

这毫无意义。如果你的代码需要注释才能被理解,是时候重构了。

改用有意义的命名:

bool isUserEligibleForAccess = user.IsActive;

干净的代码应该像散文一样可读。注释不应成为糟糕命名或复杂逻辑的遮羞布。

3. 死代码

比糟糕代码更可怕的是什么?完全无用的代码。

public void ObsoleteMethod()
{
    // 旧的业务逻辑,可能以后会用
    // DoSomethingImportant();
}

实话告诉你:你永远不会再用到它。版本控制就是干这个的。

现在就删除它。 你会感谢自己的决定。

4. 空的catch块

我见过因此导致的生产事故:

try
{
    ProcessData();
}
catch (Exception)
{
    // 暂时忽略
}

"暂时忽略"?出事故后跟项目经理解释试试?

应该始终记录、重新抛出或处理异常:

catch (Exception ex)
{
    logger.LogError(ex, "数据处理失败");
    throw;
}

静默失败是最糟糕的失败。

5. 过度设计的抽象

有人曾为单一类实现创建了IUserDataRepositoryFactoryService接口。你没看错。

抽象很好——在需要的时候。但多余的层级只会让代码更难维护和上手。

简单即强大:

public interface IUserRepository
{
    User GetById(int id);
}

除非你要处理多重实现或编写库,否则清晰度永远比炫技重要。

6. 功能过多的长方法

一个需要滚屏才能看完的方法就是红色警报。它可能:

  • 验证输入
  • 处理业务逻辑
  • 记录日志
  • 发送通知

专注做好一件事:

public void CreateOrder(OrderDto orderDto)
{
    Validate(orderDto);
    var order = MapToOrder(orderDto);
    SaveOrder(order);
    NotifyCustomer(order);
}

将大函数拆分成可读、可测试的小块。

7. 紧耦合的代码

依赖注入的存在有其道理。如果你的服务类直接实例化仓储对象,就是在制造僵化代码。

public class OrderService
{
    private readonly OrderRepository _repository = new OrderRepository();
}

使用构造函数注入:

public class OrderService
{
    private readonly IOrderRepository _repository;

    public OrderService(IOrderRepository repository)
    {
        _repository = repository;
    }
}

这个简单改动为单元测试、模拟和解耦打开了大门。

终极思考

15年开发生涯让我明白:好代码不在于你添加了什么,而在于你删除了什么。

每一行多余的逻辑、每一个被忽略的异常、每一个魔法值——都会随着时间推移不断累积,拖慢你的速度,扼杀可维护性,让后来的开发者深陷技术债。

编写整洁代码不仅是技能——更是一种责任。

你不需要掌握所有模式、所有抽象或所有花哨的新库。你只需要删除那些不该存在的东西。

而这,有时候是最难的一课。

(后续我将深入探讨如何在企业级应用中重构这7类问题,分享遗留系统清理策略和现代C#最佳实践,让你的未来为现在的决定感到自豪)

相关留言评论
昵称:
邮箱:
阅读排行