Ser*_*694 8 .net c# visual-studio roslyn .net-core
我注意到C#8.0编译器为IDisposable使用C#8.0使用声明声明的捕获变量构建闭包类的方式有所不同,这与经典的using声明声明的变量不同。
考虑这个简单的类:
public class DisposableClass : IDisposable
{
public void Dispose() { }
}
Run Code Online (Sandbox Code Playgroud)
和此示例代码:
public void Test()
{
using var disposable1 = new DisposableClass();
using var disposable2 = new DisposableClass();
Action action = () => Console.Write($"{disposable1}{disposable2}");
}
Run Code Online (Sandbox Code Playgroud)
编译器生成以下代码:
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public DisposableClass disposable1;
public DisposableClass disposable2;
internal void <Test>b__0()
{
Console.Write(string.Format("{0}{1}", disposable1, disposable2));
}
}
public void Test()
{
<>c__DisplayClass0_0 <>c__DisplayClass0_ = new <>c__DisplayClass0_0();
<>c__DisplayClass0_.disposable1 = new DisposableClass();
try
{
<>c__DisplayClass0_.disposable2 = new DisposableClass();
try
{
Action action = new Action(<>c__DisplayClass0_.<Test>b__0);
}
finally
{
if (<>c__DisplayClass0_.disposable2 != null)
{
((IDisposable)<>c__DisplayClass0_.disposable2).Dispose();
}
}
}
finally
{
if (<>c__DisplayClass0_.disposable1 != null)
{
((IDisposable)<>c__DisplayClass0_.disposable1).Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
看起来很好。但是后来我注意到,如果我使用using语句声明这两个变量,则闭包类的生成方式会大不相同。这是示例代码:
public void Test()
{
using (var disposable1 = new DisposableClass())
using (var disposable2 = new DisposableClass())
{
Action action = () => Console.Write($"{disposable1}{disposable2}");
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我得到的:
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public DisposableClass disposable1;
}
[CompilerGenerated]
private sealed class <>c__DisplayClass0_1
{
public DisposableClass disposable2;
public <>c__DisplayClass0_0 CS$<>8__locals1;
internal void <Test>b__0()
{
Console.Write(string.Format("{0}{1}", CS$<>8__locals1.disposable1, disposable2));
}
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?其余代码看起来相同,我认为using声明应该与using语句完全相同, using语句被视为阻塞了在其中声明的当前块。
不说的方式封闭类是使用声明看起来更清晰的方式产生的,并且最重要的是,提多更容易通过反射探索。
如果有人知道为什么会这样,我很乐意提供一些见识。
谢谢!
编译器[CompilerGenerated] class为每个“作用域” 生成一个...在第一个示例中,只有一个作用域,即整个Test()方法。在第二个示例(您不提供)中,有两个范围,两个using。
第二个示例的代码可能是:
public void Test()
{
using (var disposable1 = new DisposableClass())
{
using (var disposable2 = new DisposableClass())
{
Action action = () => Console.Write($"{disposable1}{disposable2}");
}
}
}
Run Code Online (Sandbox Code Playgroud)
如juharr所述,这两个代码块产生相同的代码:
using (DisposableClass disposable1 = new DisposableClass(), disposable2 = new DisposableClass())
{
Action action = () => Console.Write($"{disposable1}{disposable2}");
}
Run Code Online (Sandbox Code Playgroud)
和
using var disposable1 = new DisposableClass();
using var disposable2 = new DisposableClass();
Action action = () => Console.Write($"{disposable1}{disposable2}");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |