简体   繁体   English

我如何传递一组委托以运行到方法中

[英]How can I pass a collection of delegates to be run into a method

Referencing the sample below, is there a way to pass the work done by GetType1s() and GetType2s() in on this constructor? 参考下面的示例,是否可以通过此构造函数传递GetType1s()和GetType2s()完成的工作? I'm looking for something along the lines of a List <Action> so that I can just run each action iteratively from within the constructor without caring about what it does, but I can't think of an appropriate way to do that in which variables are set (and of different types). 我正在寻找类似于List <Action>这样我就可以从构造函数中迭代地运行每个动作,而不必关心它的作用,但是我想不出一种合适的方法来执行此操作设置变量(以及不同类型)。 I realize this is getting awfully close to DI and IOC, so maybe there's no way out of creating a container if I want to pass this work into the class like this? 我意识到这已经非常接近DI和IOC,所以如果我想将这项工作传递给这样的类,也许可能没有办法创建一个容器吗?

      public MainPageViewModel(string taskBaseLocation)
    {
        TasksBaseLocation = taskBaseLocation;
        Type1List = TasksModel.GetType1s(TasksBaseLocation);
        Type2List = TasksModel.GetType2s(TasksBaseLocation);
    }

Declare an appropriate delegate type and pass that in a generic list. 声明适当的委托类型并将其传递给通用列表。

public delegate retType MyDelegate(param1type param1, param2type param2,...)

List<MyDelegate> listToPass = new List<MyDelegate>();

Since delegates are multicast, just pass an Action : 由于委托是多播的,因此只需传递一个Action

if(action != null) { action(); } 

and combine at the caller. 并在呼叫者处合并。

If you need to run them independently (for example, to run later actions even if earlier actions fail), de-construct it: 如果您需要独立运行它们(例如,即使先前的操作失败,也要运行后续的操作),请对其进行解构:

if(action != null)
{
    foreach(Action child in action.GetInvocationList())
    {
        try
        {
            child();
        }
        catch (Exception ex)
        {
             // handle/log etc
        }
    }
}

Note, however, that this doesn't magically provide access to the member variables from the delegate, unless the delegate's context already had access to the fields (and a reference to the new instance, perhaps via Action<T> instead of Action ) 但是请注意,除非代理的上下文已经可以访问字段(以及对新实例的引用,可能是通过Action<T>而不是Action ),否则这不能从委托神奇地提供对成员变量的访问。

I have two approaches here, using pure lambdas or using Delegate.Combine. 我在这里有两种方法,使用纯lambda或使用Delegate.Combine。 I'd prefer the lambda variety. 我更喜欢lambda品种。

using System;
using System.Linq;

namespace X
{
    public class MyType
    {
        public delegate void DoInitialize(MyType instance);
        public int a,b,c;

        public MyType(DoInitialize initialize) 
        {
            initialize(this);
        }

        public MyType(params Action<MyType>[] initializers) 
        {
            foreach (var initializer in initializers)
                initializer(this);
        }

        public static void LambdaApproach()
        {
            var instance = new MyType(
                    i => i.a = 1,
                    i => i.b = 2,
                    i => i.c = 42);
            Console.WriteLine("{0}, {1}, {2}", instance.a, instance.b, instance.c);
        }

        public static void MulticastApproach()
        {
            var lambdas = new DoInitialize[] {
                    i => i.a = 1,
                    i => i.b = 2,
                    i => i.c = 42, };

            var instance = new MyType((DoInitialize) Delegate.Combine(lambdas.ToArray()));
            Console.WriteLine("{0}, {1}, {2}", instance.a, instance.b, instance.c);
        }

        public static void Main(string[] args)
        {
            LambdaApproach();
            MulticastApproach();
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM