我正在尝试创建一个接口,该接口的属性可能是实际实现的Action
或Action<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
}
必须以T
或Action
的形式传递Action<T>
参数,这是创建属性Action的泛型类型列表的问题。
此的真正实现用于UI自动化过程中。我迷上了AutomationElement
,并听着WindowPattern.WindowOpening
事件,该事件将触发内部foreach循环。这个想法是要有一个要侦听的预定义窗口列表,以及当该窗口打开时要调用的方法。其中一些方法需要一个参数,而某些则不需要-Action
和Action<T>
。
我真的可以朝正确的方向轻推。
edit:包括了简单区域,因为这是当前代码,我将其提供为我要去的地方的上下文。
答案 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) }
};