一、顶级语句:告别 Main 方法的束缚

以前写C#程序,总得老老实实写个 class Programstatic void Main,就像进门必须换拖鞋一样,虽然规矩但有点烦。.NET 6 的顶级语句(Top-level statements)直接把这道门槛拆了——现在你可以像写Python脚本一样,直接在文件里写执行代码!

示例1:最简单的"Hello World"

// 技术栈:.NET 6 Console Application
// 直接写执行代码,不需要类和方法声明
Console.WriteLine("摸鱼程序员的第一行代码!"); 

实际应用场景

  • 快速原型开发(比如临时测试某个NuGet包)
  • 编写小工具脚本(替代PowerShell/Bash脚本)
  • 教学演示时减少认知负担

注意事项

  1. 一个项目只能有一个文件使用顶级语句
  2. 仍然会编译成传统的Main方法,只是语法糖
  3. 不适合大型项目的主入口

二、隐式 using:少写90%的using语句

每次新建文件都要手动加 using Systemusing System.Collections.Generic,这种重复劳动终于可以结束了!.NET 6 的隐式全局 using 通过 <ImplicitUsings>enable</ImplicitUsings> 配置自动引入常用命名空间。

示例2:看隐式using多省事

// 技术栈:.NET 6 Web API
var list = new List<string>(); // 不需要using System.Collections.Generic
Console.WriteLine(list.Count);  // 不需要using System

// 在.csproj文件中配置:
// <PropertyGroup>
//   <ImplicitUsings>enable</ImplicitUsings>
// </PropertyGroup>

关联技术
可以通过 GlobalUsings.cs 文件自定义全局命名空间:

// 手动添加第三方库的全局using
global using Newtonsoft.Json; 
global using Microsoft.EntityFrameworkCore;

优缺点分析
✔️ 优点:减少模板代码,提升开发速度
❌ 缺点:可能引起命名冲突(比如同时引入两个同名扩展方法)

三、泛型Attribute:给元数据加上类型安全

以前写Attribute时参数都是 object 类型,运行时才能发现类型错误。现在可以用泛型Attribute了,编译时就能检查类型!

示例3:验证用户权限的泛型Attribute

// 技术栈:.NET 6 Web API
[AttributeUsage(AttributeTargets.Method)]
public class PermissionAttribute<T> : Attribute where T : Enum
{
    public T RequiredPermission { get; }

    public PermissionAttribute(T permission)
    {
        RequiredPermission = permission;
    }
}

// 使用强类型枚举作为参数
public enum UserPermission { Read, Write, Delete }

[Permission(UserPermission.Write)] // 编译时检查类型
public void UpdateData() { }

高级用法:结合反射动态检查权限

var method = typeof(MyController).GetMethod("UpdateData");
var attr = method.GetCustomAttribute<PermissionAttribute<UserPermission>>();

if (attr.RequiredPermission != currentUser.Permission) {
    throw new UnauthorizedException();
}

四、实战组合应用:构建高效命令行工具

把三个特性结合起来,我们做个数据库查询小工具:

示例4:组合技实战

// 技术栈:.NET 6 + SQLite
// 不需要Main方法,直接开始写业务逻辑
using var db = new DatabaseContext();

// 使用隐式using的Console类
Console.WriteLine("输入查询关键词:");  
var keyword = Console.ReadLine();

// 泛型Attribute标记的查询方法
var results = Query<User>(keyword, u => u.Name.Contains(keyword));

// 使用顶级语句的局部函数
IEnumerable<T> Query<T>(string keyword, Func<T, bool> predicate) where T : class 
    => db.Set<T>().Where(predicate).ToList();

// 泛型Attribute定义(实际项目应放在单独文件)
[AttributeUsage(AttributeTargets.Method)]
public class LogExecutionTimeAttribute<T> : Attribute { /*...*/ }

五、技术选型建议

  1. 团队协作项目:慎用顶级语句,建议只在工具类项目中使用
  2. 遗留项目升级:隐式using可以立即启用,几乎无副作用
  3. 框架开发:优先采用泛型Attribute提升API健壮性

六、避坑指南

  1. 顶级语句文件中如果声明了类,必须放在所有代码之后
  2. 隐式using可能会意外引入不需要的命名空间(如System.Drawing)
  3. 泛型Attribute不能被非泛型Attribute继承

七、性能影响

  • 顶级语句:零开销(编译后就是普通Main方法)
  • 隐式using:增加编译时间(约5%-8%),不影响运行时
  • 泛型Attribute:相比传统Attribute有轻微内存优势

八、总结

这三个特性看似简单,但组合起来能显著提升开发体验。特别是对于经常需要写小工具的后端开发者来说,顶级语句+隐式using简直就是摸鱼神器!而泛型Attribute则为框架开发者提供了更严格的类型检查手段。

建议从隐式using开始尝试,逐步在合适场景应用其他特性。记住:新特性不是用来炫技的,关键是找到它们最适合的应用场景。