tags:

views:

51

answers:

2

I am invoking a delegate and I'm not very informed about how it works and I have compilation errors because of it (Compiler Error CS1660). This is the code I have for it:

 base.Invoke( delegate {
            bool flag = (((this.layerPickPlaceProcess != null) && (this.robotComponent != null)) && ((((StateEnum) this.layerPickPlaceProcess.State) == StateEnum.Idle) || (((StateEnum) this.layerPickPlaceProcess.State) == StateEnum.Ready))) && ((((StateEnum) this.robotComponent.State) == StateEnum.Idle) || (((StateEnum) this.robotComponent.State) == StateEnum.Ready));
            this.cmdManualPlace.Enabled = flag;
        });
+4  A: 

add (Action):

 base.Invoke( (Action)delegate {
            bool flag = (((this.layerPickPlaceProcess != null) && (this.robotComponent != null)) && ((((StateEnum) this.layerPickPlaceProcess.State) == StateEnum.Idle) || (((StateEnum) this.layerPickPlaceProcess.State) == StateEnum.Ready))) && ((((StateEnum) this.robotComponent.State) == StateEnum.Idle) || (((StateEnum) this.robotComponent.State) == StateEnum.Ready));
            this.cmdManualPlace.Enabled = flag;
        });

this is because Invoke accepts Delegate which is not (sic!) a delegate type as far as the C# compiler is concerned. A delegate type should define a call signature, while Delegate does not and is just a common ancestor. The expression delegate { ... } has type... try to guess... anonymous delegate (if it was a method it would be method group). They are not delegate types either! But they can be implicitly converted to a delegate type that has a matching signature. And delegate types can be implicitly converted to Delegate.

Action is: public delegate void Action();

simply, chains:

  • Anonymous methodDelegate: no conversion exists
  • Anonymous methodAction: implicit conversion if signature matches
  • ActionDelegate: implicit conversion (Action is descendant of Delegate)

Combine them:

  • Anonymous methodActionDelegate: it works!
Andrey
I need at least one parameter for Action<>. do i dare try Action<Delegate>?
mookie
@mookie there is delegate type `Action` without params
Andrey
Best answer so far.
Timwi
+1: Much better explanation than mine.
Ani
+2  A: 

Try this:

// MethodInvoker is also acceptable.
Action action = delegate
        {
            bool flag = (((this.layerPickPlaceProcess != null) && (this.robotComponent != null)) && ((((StateEnum) this.layerPickPlaceProcess.State) == StateEnum.Idle) || (((StateEnum) this.layerPickPlaceProcess.State) == StateEnum.Ready))) && ((((StateEnum) this.robotComponent.State) == StateEnum.Idle) || (((StateEnum) this.robotComponent.State) == StateEnum.Ready));
            this.cmdManualPlace.Enabled = flag;
        };

base.Invoke(action);

You have to tell the complier a specific delegate-type to use; there could be any number of delegate-types that are compatible with an anonymous method.

You might find this MSDN page helpful, although it doesn't mention why the C# compiler doesn't consider System.Delegate to be a delegate-type, which is the real problem here.

Ani
Not wrong, but would be nice to mention one of the two syntaxes that allows this to be written in one statement without a temporary variable.
Timwi