ILSpy
ILSpy copied to clipboard
Issue when decompiling private VB.NET WithEvents fields
Input code
.property instance class [System.Windows.Forms]System.Windows.Forms.Timer My_Timer()
{
.get instance class [System.Windows.Forms]System.Windows.Forms.Timer MyForm.MyClass::get_My_Timer()
.set instance void MyForm.MyClass::set_My_Timer(class [System.Windows.Forms]System.Windows.Forms.Timer)
}
.method private specialname newslot strict virtual
instance class [System.Windows.Forms]System.Windows.Forms.Timer get_My_Timer () cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x31f4
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld class [System.Windows.Forms]System.Windows.Forms.Timer MyForm.MyClass::_My_Timer
IL_0006: ret
} // end of method MyClass::get_My_Timer
.method private specialname newslot strict virtual
instance void set_My_Timer (
class [System.Windows.Forms]System.Windows.Forms.Timer WithEventsValue
) cil managed synchronized
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x8428
// Header size: 12
// Code size: 55 (0x37)
.maxstack 2
.locals init (
[0] class [mscorlib]System.EventHandler,
[1] class [System.Windows.Forms]System.Windows.Forms.Timer
)
IL_0000: ldarg.0
IL_0001: ldftn instance void MyForm.MyClass::My_Timer_Elapsed(object, class [mscorlib]System.EventArgs)
IL_0007: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int)
IL_000c: stloc.0
IL_000d: ldarg.0
IL_000e: ldfld class [System.Windows.Forms]System.Windows.Forms.Timer MyForm.MyClass::_My_Timer
IL_0013: stloc.1
IL_0014: ldloc.1
IL_0015: brfalse.s IL_001e
IL_0017: ldloc.1
IL_0018: ldloc.0
IL_0019: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Timer::remove_Tick(class [mscorlib]System.EventHandler)
IL_001e: ldarg.0
IL_001f: ldarg.1
IL_0020: stfld class [System.Windows.Forms]System.Windows.Forms.Timer MyForm.MyClass::_My_Timer
IL_0025: ldarg.0
IL_0026: ldfld class [System.Windows.Forms]System.Windows.Forms.Timer MyForm.MyClass::_My_Timer
IL_002b: stloc.1
IL_002c: ldloc.1
IL_002d: brfalse.s IL_0036
IL_002f: ldloc.1
IL_0030: ldloc.0
IL_0031: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Timer::add_Tick(class [mscorlib]System.EventHandler)
IL_0036: ret
} // end of method MyClass::set_My_Timer
Erroneous output
private virtual Timer My_Timer
{
[CompilerGenerated]
get
{
return _My_Timer;
}
[MethodImpl(MethodImplOptions.Synchronized)]
[CompilerGenerated]
set
{
EventHandler value2 = my_Timer_Elapsed;
Timer my_Timer = _My_Timer;
if (my_Timer != null)
{
my_Timer.Tick -= value2;
}
_My_Timer = value;
my_Timer = _My_Timer;
if (my_Timer != null)
{
my_Timer.Tick += value2;
}
}
}
And obviously fails to compile with Error CS0621 '...': virtual or abstract members cannot be private
Note: I opened the assembly and used the "Save code". But its identical to what ILSpy shows me so decompilation is incorrect.
Details
- Product in use: ILSpy
- Version in use: 8.2.0.7535
- Target assembly is a .NET Framework Winforms application
This is a VB.NET assembly that contains the following field declaration:
Private WithEvents My_Timer As Timer
The VB compiler emits the field as a virtual property to make sure that all events are properly registered/unregistered when the value of the field (re)assigned. Unfortunately this cannot be represented in C# and I am not sure why this is even considered valid in metadata. The best we could do is not emitting the virtual
modifier, but that would not help you much, because there will be a lot of other compiler errors anyway.
See also #2602