属性Action和Action <T>的接口

时间:2019-11-18 05:00:01

标签: c# generics automation

我正在尝试创建一个接口,该接口的属性可能是实际实现的ActionAction<T>。传入的某些方法不需要参数,有些则不需要参数。

在研究并尝试了几种方法之后,这就是我要去的地方:

using System;
using System.Collections.Generic;

namespace InterfaceProperty
{
    class Program
    {
        static void Main(string[] args)
        {
            var ClassItems = new List<SomeClass>()
            {
                new SomeClass() { TitleProp = "Foo" },
                new SomeClass() { TitleProp = "Bar" }
            };

            #region Simple
            var SimpleActions = new List<SimpleAction>()
            {
                new SimpleAction() { Title = "Foo", Action = MethodWithoutParam },
                new SimpleAction() { Title = "Bar", Action = MethodWithoutParam }
            };

            foreach (var item in ClassItems)
            {
                // In "real life" this would be triggered in an event, and the parent loop would not be required.
                foreach (var simpleAction in SimpleActions)
                {
                    if (simpleAction.Title == item.TitleProp)
                    {
                        simpleAction.Action();
                    }
                }
            }
            #endregion

            #region Complicated
            var ComplicatedActions = new List<IGenericAction<Action>>()
            {
                new GenericAction<Action>() { Title = "Foo", Action = MethodWithoutParam },
                new GenericAction<Action<string>>() { Title = "Bar", Action = MethodWithParam } // fails here
            };

            foreach (var item in ClassItems)
            {
                // In "real life" this would be triggered in an event, and the parent loop would not be required.
                foreach (var genericAction in ComplicatedActions)
                {
                    if (genericAction.Title == item.TitleProp)
                    {
                        genericAction.Action();
                    }
                }
            }

            #endregion

            Console.ReadLine();
        }

        private static void MethodWithoutParam()
        {
            Console.WriteLine("Method without a parameter");
        }

        private static void MethodWithParam(string param)
        {
            Console.WriteLine($"Method with parameter: {param}");
        }
    }

    public class SomeClass
    {
        public string TitleProp { get; set; }
    }

    #region Simple
    public class SimpleAction
    {
        public string Title { get; set; }
        public Action Action { get; set; }
    }
    #endregion

    #region Complicated
    public interface IGenericAction<T>
    {
        string Title { get; set; }
        T Action { get; set; }
    }

    public class GenericAction<T> : IGenericAction<T>
    {
        public string Title { get; set; }
        public T Action { get; set; }
    }
    #endregion
}

必须以TAction的形式传递Action<T>参数,这是创建属性Action的泛型类型列表的问题。

此的真正实现用于UI自动化过程中。我迷上了AutomationElement,并听着WindowPattern.WindowOpening事件,该事件将触发内部foreach循环。这个想法是要有一个要侦听的预定义窗口列表,以及当该窗口打开时要调用的方法。其中一些方法需要一个参数,而某些则不需要-ActionAction<T>

我真的可以朝正确的方向轻推。

edit:包括了简单区域,因为这是当前代码,我将其提供为我要去的地方的上下文。

1 个答案:

答案 0 :(得分:1)

只要在构造GenericAction时知道该参数,就可以将对MethodWithParam的调用写为:

Action action = () => MethodWithParam("my parameter");

然后,您不再需要T中的GenericAction

string p1 = "parameter one";
var complicatedActions = new List<IGenericAction>()
{
    new GenericAction() { Title = "Foo", Action = MethodWithoutParam },
    new GenericAction() { Title = "Bar", Action = () => MethodWithParam(p1) } 
};