1

I decompiled a .net 4.6.1 project dll with dotpeek. After decompiling I have the following error:

CS1660 Cannot convert to 'Delegate' because type is not of delegate type

private void MainLogAdd(string s, System.Drawing.Color color)
    {
      this.logcol.Add(color);
      this.lstLogBox.Invoke((delegate) (() =>
      {
        this.lstLogBox.Items.Add((object) ("[" + DateTime.Now.TimeOfDay.ToString().Substring(0, 8) + "] " + s));
        this.lstLogBox.TopIndex = this.lstLogBox.Items.Count - 1;
      }));
    }

After change with new Action 'Action 1 does not contain a constructor that takes its arguments' '

eray erkol
  • 15
  • 5
  • This is a mismash of two syntaxes, each valid separately. `delegate(typed argument list) { code here }` has been available since C# 2.0, while `(arg names, types optional) => {code here}` was introduced later to allow omitting types that can be inferred. The first syntax has a different advantage... leaving out the argument list makes it compatible with any argument list. In the first syntax, parentheses are not allowed around the keyword `delegate`. – Ben Voigt Oct 26 '20 at 16:31

3 Answers3

3

I believe it'll work out if you simply change (delegate) to (Action) instead

Before:

this.lstLogBox.Invoke((delegate) (() =>

After:

this.lstLogBox.Invoke((Action) (() =>

Here's an example:

enter image description here

Edit

You say you have a class called Action already and it's causing a conflict. You can use the full name:

this.lstLogBox.Invoke((System.Action) (() =>

Or you can create an alias by e.g. putting this at the top of your class:

using SystemAction = System.Action;

Then using the alias..

this.lstLogBox.Invoke((SystemAction) (() =>

Or you can rename your class :)

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • I have a class named Action so ı cant use this delegate Action ı sellect Action<> in list but its sellect my class :( – eray erkol Oct 26 '20 at 16:35
  • Then `System.Action`. It's possible that the colliding names are somehow related to the decompiler bug, but more likely that the decompiler just has unfinished support for decompiling to lambdas – Ben Voigt Oct 26 '20 at 16:39
  • Thank you so much Sir – eray erkol Oct 26 '20 at 16:42
2

Replace (delegate) with new System.Action:

    this.lstLogBox.Invoke(new System.Action(() =>
    {
        this.lstLogBox.Items.Add((object) ("[" + DateTime.Now.TimeOfDay.ToString().Substring(0, 8) + "] " + s));
        this.lstLogBox.TopIndex = this.lstLogBox.Items.Count - 1;
    }));

The Invoke method accepts a parameter of type Delegate, which is an abstract class and the base type for all delegates.

Lambda expressions may compile to expression trees (Expression<Func<...>>) or plain delegates (Action or Func). The C# compiler needs to know the exact type of the delegate, so it can generate the code for the lambda expression.

By the way, that's the problem with most C# decompilers. I had the best luck with ILSpy.

Mohammad Dehghan
  • 17,853
  • 3
  • 55
  • 72
0

The value passed to .Invoke() needs to be an actual instantiated delegate type such as Action because the Windows Forms library was created before lambdas existed in C#. Instead of casting the lambda to a delegate like the decompiler wrote, it should read something like this:

this.lstLogBox.Invoke(new Action(() => { ... }));
Arcanox
  • 1,420
  • 11
  • 20