存储和调用具有多个未知参数的未知方法的委托?

时间:2014-06-13 20:05:52

标签: c# delegates system.reflection

希望我有正确的术语。希望使一个CSharp委托接收一个包含0个或更多未知参数的未知函数。存储所有这些..然后在存储它时使用参数调用存储的方法。

我检查了很多线程和消息,但还没有找到一个可靠的答案。有几个地方导致了成功的解决方法,但可用性需要一些“漂亮”代码的“语法糖”。

帮助会很精彩!

...以下代码有效:

  

InvokeManager.Eval(1f,new System.Action(MyDelayedMethod),   new object [] {“some argument data”,3412,true});

......这是句法目标,可以吗?我们能有多接近?:

  

InvokeManager.Eval(1f,Log(“some argument data”,3412,true));

...工作代码段:

    public class InvokeContainer : IComparable<InvokeContainer>
    {
            int _activationStamp;
            Delegate _delayedFun;
            object[] _args;

            public int ActivationTimestamp {
                    get { return _activationStamp; }
            }

            public Delegate Callback {
                    get { return _delayedFun; }
            }

            public object[] Args {
                    get { return _args; }
            }

            public InvokeContainer(float delay, NcTickTimerTool timer, Delegate method, object[] args )
            {
                    _args = args;
                    _delayedFun = method;
                    _activationStamp = (int)(1000f * delay) + timer.GetElapsedTickCount();
            }

            ...

    }

    public class InvokeManager
    {
            private BinaryHeap<InvokeContainer> _heap;
    ...

            public static void Eval( float delay, Delegate method, params object[] args )
            {
                    _instance._heap.Add( new InvokeContainer( delay, _instance._ticker, method, args ) );
            }

            // Gets called externally on a thread

            void Update ()
            {
                    InvokeContainer poppedCallback;
                    int currentTicks = _ticker.GetStartedTickCount();
                    int heapPeekTicks = 0;

                    if( _heap.Count>0 )
                    heapPeekTicks = ((InvokeContainer)_heap.Peek()).ActivationTimestamp;

                    // Invoke all methods which have waited long enough

                    while ( _heap.Count>0 && heapPeekTicks<=currentTicks )
                    {
                            poppedCallback = (InvokeContainer)_heap.Remove();
                            poppedCallback.Callback.DynamicInvoke( poppedCallback.Args );
                            poppedCallback = (InvokeContainer)_heap.Peek();
                            if (poppedCallback!=null)
                                    heapPeekTicks = poppedCallback.ActivationTimestamp;
                            else
                                    break;
                    }
            }

    ...

    }

1 个答案:

答案 0 :(得分:3)

不是接受具有未知数量参数的委托,而是接受Action(或Func<T>,如果您需要计算结果),并且调用者可以关闭他们可能需要的任何值使用lambda在他们的委托中使用。

除了在调用者和实现上都更容易之外,它还可以确保静态类型并防止用户提供一个委托,该委托接受不同数量的参数或不同类型的参数,以及它们提供的值它