传递要针对具体实现列表执行的 Action<interface>
Passing an Action<interface> to to be executed against list of concrete implementations
所以我有这个
public interface ITask
{
void PrintName(string props);
void PrintState();
}
public class Epic: ITask
{
public Epic() { }
public void PrintName(string props)
{
Console.WriteLine("Hello Epic: " + props);
}
public void PrintState(string props)
{
Console.WriteLine("Epic Started");
}
}
public class Story: ITask
{
public Story() { }
public void PrintName(string props)
{
Console.WriteLine("Hello Story: " + props);
}
public void PrintState(string props)
{
Console.WriteLine("Story Started");
}
}
public class TaskProxy : ITask
{
List<ITask> list;
public TaskProxy (List<ITask> list)
{
this.list = list;
}
public void PrintName(string props)
{
foreach(ITask tsk in list)
{
tsk.PrintName(props);
}
}
public void PrintState()
{
foreach(ITask tsk in list)
{
tsk.PrintState();
}
}
}
我执行的是
class Program
{
static List<ITask> list = new List<ITask>();
static void Main(string[] args)
{
list.Add(new Story());
list.Add(new Epic());
ITask task = TaskProxy(list );
task.PrintName("some props")
task.PrintState()
}
}
但我希望将其重写为 Action<> 泛型,它将在不同实现的上下文中执行所有类似的方法。 (类似于方法借用?)
public class TaskProxy : ITask
{
List<ITask> list;
public TaskProxy (List<ITask> list)
{
this.list = list;
}
public void PrintName(string props)
{
Generic(ITask.PrintName(props)) // looking for something like this
}
public void PrintState()
{
Generic(ITask.PrintState()) // looking for something like this
}
public void Generic(Action methodToExecute)
{
foreach(ITask tsk in list)
{
tsk.methodToExecute();
}
}
}
为了您的目的,反思将是一种可行的方法。解决方案可能如下所示:
using System;
using System.Collections.Generic;
using System.Reflection;
namespace CsharpPlayground
{
public class Code
{
interface ITask
{
void printName();
}
class Story : ITask
{
public void printName()
{
Console.WriteLine("Story");
}
}
class Epic : ITask
{
public void printName()
{
Console.WriteLine("Epic");
}
}
public static void Main(string[] args)
{
var tasks = new List<ITask>
{
new Story(),
new Epic()
};
// Approach 1
Console.WriteLine("Approach 1");
foreach (var task in tasks)
{
task.printName();
}
// Approach 2
Console.WriteLine("\nApproach 2");
void GenericExecuted(MethodInfo method)
{
foreach (ITask tsk in tasks)
{
method?.Invoke(tsk, new object[0]);
}
}
var printMethod = typeof(ITask).GetMethod(nameof(ITask.printName));
GenericExecuted(printMethod);
}
}
}
通用变体可能如下所示:
public void Generic(Action<ITask> iTaskMethodToExecute)
{
foreach(ITask tsk in list)
{
iTaskMethodToExecute(tsk);
}
}
说明:Action<ITask>
表示以ITask
为参数的动作。这允许您在 lambda 表达式中访问 ITask 提供的所有方法。
你会这样称呼它:
List<ITask> list = new List<ITask>();
list.Add(new Story());
list.Add(new Epic());
TaskProxy task = new TaskProxy(list );
task.Generic(x => x.PrintName("some props"));
task.Generic(x => x.PrintState());
乍一看,将 ITask
作为参数插入到操作中可能有点令人困惑,如下所示:
iTaskMethodToExecute(tsk);
但是如果你看一下 lambda 表达式调用:
task.Generic(x => x.PrintState());
^
|
input of type: ITask
它应该是有意义的,因为只有这样编译器才能推断出类型,intelisense 甚至会建议自动完成中的方法:
所以我有这个
public interface ITask
{
void PrintName(string props);
void PrintState();
}
public class Epic: ITask
{
public Epic() { }
public void PrintName(string props)
{
Console.WriteLine("Hello Epic: " + props);
}
public void PrintState(string props)
{
Console.WriteLine("Epic Started");
}
}
public class Story: ITask
{
public Story() { }
public void PrintName(string props)
{
Console.WriteLine("Hello Story: " + props);
}
public void PrintState(string props)
{
Console.WriteLine("Story Started");
}
}
public class TaskProxy : ITask
{
List<ITask> list;
public TaskProxy (List<ITask> list)
{
this.list = list;
}
public void PrintName(string props)
{
foreach(ITask tsk in list)
{
tsk.PrintName(props);
}
}
public void PrintState()
{
foreach(ITask tsk in list)
{
tsk.PrintState();
}
}
}
我执行的是
class Program
{
static List<ITask> list = new List<ITask>();
static void Main(string[] args)
{
list.Add(new Story());
list.Add(new Epic());
ITask task = TaskProxy(list );
task.PrintName("some props")
task.PrintState()
}
}
但我希望将其重写为 Action<> 泛型,它将在不同实现的上下文中执行所有类似的方法。 (类似于方法借用?)
public class TaskProxy : ITask
{
List<ITask> list;
public TaskProxy (List<ITask> list)
{
this.list = list;
}
public void PrintName(string props)
{
Generic(ITask.PrintName(props)) // looking for something like this
}
public void PrintState()
{
Generic(ITask.PrintState()) // looking for something like this
}
public void Generic(Action methodToExecute)
{
foreach(ITask tsk in list)
{
tsk.methodToExecute();
}
}
}
为了您的目的,反思将是一种可行的方法。解决方案可能如下所示:
using System;
using System.Collections.Generic;
using System.Reflection;
namespace CsharpPlayground
{
public class Code
{
interface ITask
{
void printName();
}
class Story : ITask
{
public void printName()
{
Console.WriteLine("Story");
}
}
class Epic : ITask
{
public void printName()
{
Console.WriteLine("Epic");
}
}
public static void Main(string[] args)
{
var tasks = new List<ITask>
{
new Story(),
new Epic()
};
// Approach 1
Console.WriteLine("Approach 1");
foreach (var task in tasks)
{
task.printName();
}
// Approach 2
Console.WriteLine("\nApproach 2");
void GenericExecuted(MethodInfo method)
{
foreach (ITask tsk in tasks)
{
method?.Invoke(tsk, new object[0]);
}
}
var printMethod = typeof(ITask).GetMethod(nameof(ITask.printName));
GenericExecuted(printMethod);
}
}
}
通用变体可能如下所示:
public void Generic(Action<ITask> iTaskMethodToExecute)
{
foreach(ITask tsk in list)
{
iTaskMethodToExecute(tsk);
}
}
说明:Action<ITask>
表示以ITask
为参数的动作。这允许您在 lambda 表达式中访问 ITask 提供的所有方法。
你会这样称呼它:
List<ITask> list = new List<ITask>();
list.Add(new Story());
list.Add(new Epic());
TaskProxy task = new TaskProxy(list );
task.Generic(x => x.PrintName("some props"));
task.Generic(x => x.PrintState());
乍一看,将 ITask
作为参数插入到操作中可能有点令人困惑,如下所示:
iTaskMethodToExecute(tsk);
但是如果你看一下 lambda 表达式调用:
task.Generic(x => x.PrintState());
^
|
input of type: ITask
它应该是有意义的,因为只有这样编译器才能推断出类型,intelisense 甚至会建议自动完成中的方法: