从“能用”到“卓越”:7个实战技巧提升C#代码质量

作者:微信公众号:【架构师老卢】
3-2 9:35
66

本文将揭秘七个实战技巧,助你跨越“功能实现”到“优雅代码”的鸿沟。通过正反案例对比与技术心法,重构代码思维模式,让代码兼具可读性与可维护性。


1. 命名即语义:让代码自述其意

代码即故事,变量/方法/类名如同角色命名。你会阅读主角名为xdata的小说吗?

糟糕命名

public int Calculate(int a, int b)  
{  
    int x = a + b;  
    return x * 2;  
}

问题abx毫无意义,方法功能成谜。

优雅命名

public int CalculateDiscountedTotal(int basePrice, int taxAmount)  
{  
    int subtotal = basePrice + taxAmount;  
    return subtotal * 2; // 隐含50%折扣逻辑
}

优势:方法名CalculateDiscountedTotal与变量subtotal自述功能,无需注释。

命名法则

  • 方法 → 动词(GetUserProfileValidateEmail
  • → 名词(OrderProcessorPaymentGateway
  • 变量 → 描述性(customerAddressisAccountLocked

2. 单一职责:方法拆分之道

方法应专注单一任务。若需用“并且”描述功能,立即拆分!

臃肿方法

public void ProcessOrder(Order order)  
{  
    if (order == null) throw new ArgumentNullException();  
    // 验证商品  
    foreach (var item in order.Items)  
    {  
        if (item.Quantity < 0)  
            throw new InvalidOperationException();  
    }  
    // 计算总额  
    decimal total = order.Items.Sum(i => i.Price * i.Quantity);  
    // 持久化  
    _dbContext.Orders.Add(order);  
    _dbContext.SaveChanges();  
}

问题:杂糅验证、计算、持久化逻辑。

职责拆分

public void ProcessOrder(Order order)  
{  
    ValidateOrder(order);  
    CalculateTotal(order);  
    SaveOrder(order);  
}  

private void ValidateOrder(Order order) { /* 验证逻辑 */ }  
private void CalculateTotal(Order order) { /* 计算逻辑 */ }  
private void SaveOrder(Order order) { /* 持久化逻辑 */ }

优势:每方法专注单一职责,修改验证逻辑不影响持久化模块。


3. 消灭魔法数值与字符串

代码中散落的裸数值/字符串是定时炸弹,用常量或枚举替代。

魔法值陷阱

if (user.Status == 3)  
{  
    SendEmail("approved");  
}

问题3"approved"含义不明。

自解释代码

public enum UserStatus  
{  
    Pending = 1,  
    Active = 2,  
    Approved = 3  
}  

public class EmailTemplates  
{  
    public const string Approved = "approved";  
}  

if (user.Status == UserStatus.Approved)  
{  
    SendEmail(EmailTemplates.Approved);  
}

优势:代码即文档,消除猜测成本。


4. 异常处理:优雅应对而非忽视

吞没异常或写catch (Exception ex) { }如同无视汽车故障灯。

错误处理

try  
{  
    File.ReadAllText("config.json");  
}  
catch (Exception)  
{  
    // 静默失败
}

问题:静默失败导致后续未知崩溃。

专业处理

try  
{  
    string config = File.ReadAllText("config.json");  
}  
catch (FileNotFoundException ex)  
{  
    _logger.LogError($"配置文件缺失: {ex.Message}");  
    throw; // 抛给上层处理
}

原则

  • 捕获具体异常
  • 记录日志供调试
  • 由调用方决定恢复策略

5. 善用C#语言特性

活用语言特性减少样板代码,提升可读性。

LINQ替代循环

// ❌ 传统循环  
List<string> activeUsers = new List<string>();  
foreach (var user in users)  
{  
    if (user.IsActive)  
        activeUsers.Add(user.Name);  
}  

// ✅ LINQ表达式  
var activeUsers = users  
    .Where(u => u.IsActive)  
    .Select(u => u.Name)  
    .ToList();

属性优于公共字段

// ❌  
public string Name;  

// ✅  
public string Name { get; set; } 

表达式主体简化

// ❌  
public string FullName  
{  
    get { return $"{FirstName} {LastName}"; }  
}  

// ✅  
public string FullName => $"{FirstName} {LastName}";

6. 代码格式化:统一即美

不一致的格式如同混搭袜子——功能无碍,但令人分神。

风格指南

  • 大括号风格:Allman(新行)或K&R,团队统一
  • 缩进:4空格(C#社区标准)
  • 参数对齐:垂直对齐提升可读性
// ✅ 优雅对齐  
public void RegisterUser(  
    string username,  
    string email,  
    DateTime registrationDate,  
    bool isPremium = false)  
{  
    // ...  
}

自动化工具

  • EditorConfig:跨团队统一风格
  • Roslyn Analyzers:自动检测格式问题

7. 单元测试:代码的安全网

测试不仅是QA工具,更是代码行为的活文档。

xUnit示例

public class CalculatorTests  
{  
    [Fact]  
    public void Add_TwoPositiveNumbers_ReturnsSum()  
    {  
        // 准备  
        var calculator = new Calculator();  

        // 执行  
        int result = calculator.Add(3, 5);  
        // 断言  
        Assert.Equal(8, result);  
    }  
}

命名规范方法名_场景_预期结果,失败原因一目了然。


优雅代码源于习惯

编写优雅的C#代码不求完美,但需持续改进。从小处着手:

  • 今日重构一个混乱方法
  • 删除注释,让代码自解释
  • 为复杂逻辑编写测试

记住:代码被阅读的次数远多于编写。每一行都是写给未来自己或同事的情书。现在,让Bob大叔(和你的团队)为你骄傲!

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