🔍 using
的本意是什么?
using
是 C# 中用于 自动释放资源 的语法糖,适用于实现了 IDisposable
接口的对象(比如数据库连接、文件、网络流等)。
🧐 首先看下SqlSugarClient类部分源码:
SqlSugarClient类 确实 实现了 IDisposable
接口,并且实现了IDisposable
里面Void Dispose()方法。
📝 SqlSugarClient类实现了IDisposable接口:
📝 SqlSugarClient类实现了Dispose方法:
📝 IDisposable接口里Dispose方法的声明:
🔍 接下来在 using 关键字处 hover 下
可以看到当鼠标hover到using关键字的时候直接定位到了SqlSugarClient类实现了的Dispose方法。
❓ 这里有疑问,为什么hover到using关键字后会直接定位到SqlSugarClient.Dispose()呢?按F12又会直接定位到SqlSugarClient.Dispose()方法具体实现。根本看不懂using是咋做到的。常规思路想using是个函数,括号里是参数,using方法里帮忙转调Dispose。
📝 来看看AI怎么说:
🧠 那么 using
是如何工作的呢?
以你写的这段代码为例:
using (SqlSugarClient dbClient = SqlSugarInstance.GetInstance())
{// do something
}
在编译后,相当于变成了这样👇(可以理解为 using
背后的真实实现):
SqlSugarClient dbClient = SqlSugarInstance.GetInstance();
try
{// do something
}
finally
{if (dbClient != null)((IDisposable)dbClient).Dispose();
}
✅ 所以总结:
-
using
本质是语法糖,不能 F12 看到它本身的实现。 -
它会在编译阶段转换为
try-finally
并调用Dispose()
。 -
你可以通过 Sharplab.io 这种在线工具来看到编译器“反糖”的结果(即:C# 源代码编译后生成的 IL 或自动展开的样子)。
🔍 想自己验证一下?
你可以把这段代码贴进 SharpLab:
using System;
public class Test
{public static void Main(){using (var resource = new MyDisposable()){Console.WriteLine("Inside using block");}}
}public class MyDisposable : IDisposable
{public void Dispose(){Console.WriteLine("Disposed");}
}
然后选中“C# -> Decompiled C#”或者“C# -> IL”,就能看到使用 try/finally
的样子了。
✅ 如下:终于看到了语法糖是怎样工作的。
✅ using 的主要好处
1. 自动释放资源,防止资源泄露
-
不手动调用
.Dispose()
容易忘记,导致连接没释放、文件没关闭、内存泄漏。 -
using
自动帮你搞定这一切。
2. 代码简洁,逻辑清晰
-
using
把资源的生命周期限定在一块区域内,一目了然。
3. 线程安全 & 稳定性
-
即使发生异常(比如查询失败),
finally
中的.Dispose()
依然会被调用,确保资源能安全释放。
❗但使用 using
的时候要注意:
❗不能返回依赖该资源的对象
public SqlCommand GetCommand()
{using (var conn = new SqlConnection(...)){var cmd = conn.CreateCommand(); // cmd 依赖 connreturn cmd; // ❌ conn 被释放,cmd 也无法用了}
}
这就像你关了煤气罐,还想继续煮饭——锅还在,火没了 😂
💡 提示 & 建议
SharpLab 是一个很棒的工具,但它确实有一个限制:不支持你自己引入外部 NuGet 包或引用复杂的第三方库(比如 SqlSugarClient
)。它更适合用于观察 C# 核心语法糖的转换,比如 using
, async/await
, lock
,LINQ 表达式等。
https://sharplab.io/
仅供学习参考