Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue when decompiling private VB.NET WithEvents fields #3136

Open
Symbai opened this issue Dec 8, 2023 · 1 comment
Open

Issue when decompiling private VB.NET WithEvents fields #3136

Symbai opened this issue Dec 8, 2023 · 1 comment
Labels
Bug Decompiler The decompiler engine itself

Comments

@Symbai
Copy link

Symbai commented Dec 8, 2023

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
@Symbai Symbai added Bug Decompiler The decompiler engine itself labels Dec 8, 2023
@siegfriedpammer
Copy link
Member

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

@siegfriedpammer siegfriedpammer changed the title Fails to decompile System.Windows.Forms code (like Timer) Issue when decompiling private VB.NET WithEvents fields Dec 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Decompiler The decompiler engine itself
Projects
None yet
Development

No branches or pull requests

2 participants