[Mono-bugs] [Bug 571010] New: using(){} with structs shouldn't box to invoke explicitly implemented IDisposable.Dispose method
bugzilla_noreply at novell.com
bugzilla_noreply at novell.com
Fri Jan 15 12:06:11 EST 2010
http://bugzilla.novell.com/show_bug.cgi?id=571010
http://bugzilla.novell.com/show_bug.cgi?id=571010#c0
Summary: using(){} with structs shouldn't box to invoke
explicitly implemented IDisposable.Dispose method
Classification: Mono
Product: Mono: Compilers
Version: SVN
Platform: x86-64
OS/Version: openSUSE 11.2
Status: NEW
Severity: Normal
Priority: P5 - None
Component: C#
AssignedTo: mono-bugs at lists.ximian.com
ReportedBy: jpryor at novell.com
QAContact: mono-bugs at lists.ximian.com
Found By: ---
Blocker: ---
>From §15.13 (page 248) in:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf
the statement:
using (ResourceType resource = expression) embedded-statement
should expand to
{
ResourceType resource = expression;
try {
embedded-statement
}
finally {
((System.IDisposable)resource).Dispose();
}
}
when ResourceType is a value type (struct). *Additionally*:
"casting resource to System.IDisposable shall not cause boxing
to occur."
Thus, consider the following program:
using System;
struct Foo : IDisposable {
void IDisposable.Dispose(){}
public void Dispose() {}
}
class Test {
public static void Main ()
{
using (new Foo()) {
}
}
}
Compile:
$ gmcs us.cs
Disassemble, and check out the IL for Test.Main():
// Method begins at RVA 0x20fc
.entrypoint
// Code size 26 (0x1a)
.maxstack 2
.locals init (
valuetype Foo V_0)
IL_0000: ldloca.s 0
IL_0002: initobj Foo
.try { // 0
IL_0008: leave IL_0019
} // end .try 0
finally { // 0
IL_000d: ldloc.0
IL_000e: box Foo
IL_0013: callvirt instance void class
[mscorlib]System.IDisposable::Dispose()
IL_0018: endfinally
} // end handler 0
IL_0019: ret
Notice that gmcs IS boxing here. gmcs isn't following ECMA.
Compare to what .NET CSC does; same source, different IL:
// Method begins at RVA 0x2058
.entrypoint
// Code size 30 (0x1e)
.maxstack 1
.locals init (
valuetype Foo V_0)
IL_0000: nop
IL_0001: ldloca.s 0
IL_0003: initobj Foo
.try { // 0
IL_0009: nop
IL_000a: nop
IL_000b: leave.s IL_001c
} // end .try 0
finally { // 0
IL_000d: ldloca.s 0
IL_000f: constrained. Foo
IL_0015: callvirt instance void class
[mscorlib]System.IDisposable::Dispose()
IL_001a: nop
IL_001b: endfinally
} // end handler 0
IL_001c: nop
IL_001d: ret
Notice that CSC uses a 'constrained. Foo' instead of 'box Foo' to avoid boxing.
gmcs shouldn do likewise to avoid boxing the resource.
(Note that if you don't explicitly implement IDisposable.Dispose(), gmcs will
properly avoid boxing the resource, so this is only an issue for explicitly
implemented IDisposable.Dispose() methods.)
--
Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.
More information about the mono-bugs
mailing list