我對下面的代碼一些問題:什麼時候使用語句框的參數,當它是一個結構?
using System;
namespace ConsoleApplication2
{
public struct Disposable : IDisposable
{
public void Dispose() { }
}
class Program
{
static void Main(string[] args)
{
using (Test()) { }
}
static Disposable Test()
{
return new Disposable();
}
}
}
我的問題是:
- 請問使用語句,關於
Disposable
結構工作時,Test()
箱的結構,否則不予退換? - 我該如何找到答案?
要嘗試找出我自己,我檢查了IL通過上面的代碼產生的,這裏的IL爲Main(...)
方法:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] valuetype ConsoleApplication2.Disposable CS$3$0000)
L_0000: call valuetype ConsoleApplication2.Disposable ConsoleApplication2.Program::Test()
L_0005: stloc.0
L_0006: leave.s L_0016
L_0008: ldloca.s CS$3$0000
L_000a: constrained ConsoleApplication2.Disposable
L_0010: callvirt instance void [mscorlib]System.IDisposable::Dispose()
L_0015: endfinally
L_0016: ret
.try L_0006 to L_0008 finally handler L_0008 to L_0016
}
我懷疑調用虛方法那裏, L_0010
將引入拳擊操作,但實際box
指令不在這裏。
我之所以問的原因是,前一段時間,可能是1 - 2年,我在網上看到有人對使用語句進行了「優化」評論。在這種情況下,using語句被用作對象的短時間鎖定的語法,其中在該方法中獲取了鎖,並且返回了一個結構體,在處理該結構體時,會釋放鎖,像這樣的代碼:
using (LockTheObject())
{
// use the object
}
和意見是,由IDisposable
改變LockTheObject
方法的返回類型實際使用的結構,避免了拳擊。
但我想知道這是真的還是真的。
任何人都可以指向正確的方向嗎?如果爲了看到盒子的操作,我將不得不檢查運行時的彙編代碼,請給我看一個什麼樣的例子,我很熟悉彙編代碼,所以這不是問題,但沒有跳出來在我看着那個時候。
約束和callvirt之間的相互作用是我一直在尋找,謝謝! –