Using Action as an argument in C# (mimicking a function pointer)

后端 未结 4 757
眼角桃花
眼角桃花 2021-02-06 08:05

I need to write a delegate function that can \'wrap\' some while/try/catch code around a basic UDP call to verify the link. I made it work for Func for a function that has no ar

4条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-06 08:11

    If you want this to be generic enough to handle any number of arguments, try using the non-genernic Action delegate:

    protected void udpCommand(Action command)
    {
        while(!linkDownFail)
        {
            try
            {
                command();
                break;
            }
            catch
            {
                LinkStateCallBack(ip, getLinkStatus());
                if (linkDownFail) throw new LinkDownException();
                Thread.Sleep(100);
            }
        }
        return;
    }
    

    In C# 3.0, you can call it like this:

    udpCommand(() => noParameterMethod());
    udpCommand(() => singleParameterMethod(value));
    udpCommand(() => manyParameterMethod(value, value2, value3, value4));
    

    In C# 2.0 it's a little uglier:

    udpCommand(delegate { noParameterMethod(); });
    udpCommand(delegate { singleParameterMethod(value); });
    udpCommand(delegate { manyParameterMethod(value, value2, value3, value4); });
    

    This gives you deferred execution without locking you into a particular method signature.

    EDIT

    I just notice I kinda stole Marc Gravell's comment... apologies Marc. To answer how you might reduce your duplication, you can have the Action method call the Func method, like this:

    protected void udpCommand(Action command)
    {
        udpCommand(() => { command(); return 0; });
    }
    

    I believe (and I may be wrong) that returning 0 is no more costly than (implicitly) returning void, but I may be way off here. Even it it does have a cost, it would only put a tiny itty bitty snoodge extra on the stack. In most cases, the additional cost won't ever cause you any grief.

提交回复
热议问题