如何将要运行的委托集合传递到方法中?

本文关键字:方法 集合 运行 | 更新日期: 2023-09-27 17:48:56

引用下面的示例,是否有一种方法可以将GetType1s()和GetType2s()完成的工作传递到这个构造函数中?我正在寻找沿着列表<Action>的路线,这样我就可以从构造函数内迭代地运行每个动作,而不关心它做什么,但我想不出一个合适的方法来做到这一点,其中变量设置(和不同类型)。我意识到这与DI和IOC非常接近,所以如果我想像这样将此工作传递到类中,可能没有办法创建容器?

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

如何将要运行的委托集合传递到方法中?

声明一个合适的委托类型,并在泛型列表中传递。

public delegate retType MyDelegate(param1type param1, param2type param2,...)
List<MyDelegate> listToPass = new List<MyDelegate>();

由于委托是多播的,因此只需传递Action:

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

和在调用者处合并。

如果您需要独立运行它们(例如,即使前面的操作失败也要运行后面的操作),则反构造它:

if(action != null)
{
    foreach(Action child in action.GetInvocationList())
    {
        try
        {
            child();
        }
        catch (Exception ex)
        {
             // handle/log etc
        }
    }
}
但是,请注意,这并不能神奇地提供对委托成员变量的访问,除非委托的上下文已经可以访问这些字段(以及对新实例的引用,可能通过Action<T>而不是Action)

这里有两种方法,使用纯lambda或使用Delegate.Combine。我更喜欢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();
        }
    }
}