storing/passing delegates as variables

2019-02-28 03:00发布

I am fairly new to C# and was working on a a way to implement a dynamic GUI wich uses the serial communication. I originally come from C, so the concept of function pointer is familiar.

Basicly I want to invoke a answerFunction() function when the serial command has been processed. In Theory: I have a Class lbl_txtBox_Pair which is dynamicly created on runtime. I have a Class comObject which communicates with the serial Port. I have a third class comPacket which holds all information regarding one serial command.

  1. in an Object of Class lbl_txtBox_Pair I instanciate a Packet and tell it which function should be called when the serial command is finished.
  2. I give the packet Object to the comObject Instance.
  3. after beeing processed the comObject wants to signal the original sender of the packet by calling the delegate which is stored in the Packet Object.

For some reason I can't get it to work. It tells me that the Attribute of Packet is not callable. Am I doing something teribly wrong?

Here is the Code: first the code in Class "lbl_txtBox_Pair". I create the comPacket here and give it to the comObject.

public delegate void answerHandler( comPacket packet);
public void txb_value_KeyPress(object sender, KeyPressEventArgs e)
{
   if (e.KeyChar == (char)Keys.Return)
   {
      answerHandler answerMethod = new answerHandler(this.processAnswer);
      comPacket question = new comPacket(this.command, answerMethod, 1);
      comObject.addPacket(question);
    }
 }

The constructor of comPacket. Here the delegate gets stored to be called later.

public Delegate answerFunction;
public comPacket(string cmd, Delegate func, int prio)
{
    this.cmd = cmd;
    answerFunction = func;
    this.prio = prio;
}

In the comObject the Packets get processed. When finished I want to call the function stored in the Packet. The comObject runs in a different Thread by the way.

if (this.isEndtocken(inputline))
 {
    listen = false;
    packet.answerFunction(packet);
 }

And here it is were it breaks. packet.answerFunction(packet); wont execute and says it cant be called as Method.

Can anybody see where it goes wrong? I think it seems like the delegate looses the information that it is a delegate or something. ;) Or do I have to completly restructure the code to use other types of callback / Event Methods?

2条回答
smile是对你的礼貌
2楼-- · 2019-02-28 03:41

I can't leave a comment so I have to post this as an answer instead. Delegates (and events and stuff) can usually only be "invoked" by the object that contains them.

So if you have

class MyClass {
    public event Action someEvent;
    // you can also replace Action with the name of your delegate type
}

and you try to do

MyClass x = new MyClass();
x.someEvent.Invoke();

Then that's an error. If you want other objects to be able to invoke the event, you'll have do add a method to MyClass like this:

public void InvokeMyEvent() {
    someEvent.Invoke();
}

(I forget whether you still have to do this for static events)

查看更多
可以哭但决不认输i
3楼-- · 2019-02-28 03:50

Change your comPacket to take a strongly typed delegate:

public answerHandler answerFunction;
public comPacket(string cmd, answerHandler func, int prio)
{
    this.cmd = cmd;
    answerFunction = func;
    this.prio = prio;
}

If you still want to keep the delegate reference weakly typed, you can leverage DynamicInvoke instead: http://msdn.microsoft.com/en-us/library/system.delegate.dynamicinvoke.aspx

EDIT: Another option if you want to maintain strongly typed delegates yet have different usages is to leverage generics. Your delegate can be housed in a generic class and tie its signature against that generic type.

查看更多
登录 后发表回答