c#通用处理器
本文关键字:处理器 | 更新日期: 2023-09-27 18:10:09
我有一个问题,它需要一个标准的输入组合,但是有几个算法('处理器')可以解决它。输出是一个布尔值。每个处理器只对一个特定场景有效,并且永远不会有多个处理器是有效的。
每个处理器通过向它提供一些初始输入来确定它是否有效。如果它是有效的,那么它就会根据这些初始输入计算一些信息,并存储这些信息——因为这些信息在最终的过程中是有用的。然后,如果它有效,则向处理器提供额外的输入,并返回输出。
如果没有处理器有效,则给出默认答案。
算法在伪代码中是这样的:
process(inputs)
for each processor
determine validity and get data
if valid
use data to output result
end if
end for
output default result
end
下面是一个c#示例,它在语法上是无效的。这只是一个例子,在现实生活中,输入比字符串和整数更复杂。第二个输入的计算(在人为的例子中是int i)在循环中重复执行,而第一个输入只计算一次——因此进程是否有效与处理器的结果是分离的。作为使用IEnumerable的替代方法,可以使用处理器数组或列表。
public class ProcessController
{
public static IEnumerable<Processor<X>> GetProcessors<X>() where X: ProcessorInfo
{
yield return new ProcessorA();
yield return new ProcessorB();
}
public static bool Process<X>(String s, int i) where X : ProcessorInfo
{
foreach (Processor<X> processor in GetProcessors<X>())
{
X x = (X) processor.GetInfoIfCanProcess(s);
if (x != null)
{
return processor.GetResult(x, i);
}
}
return false;
}
}
public abstract class Processor<T> where T: ProcessorInfo
{
public abstract T GetInfoIfCanProcess(String s);
public abstract bool GetResult(T info, int i);
}
public interface ProcessorInfo
{
bool IsValid();
}
public class ProcessorA: Processor<ProcessorA.ProcessorInfoA>
{
public class ProcessorInfoA: ProcessorInfo
{
public bool IsValid()
{
//do something!
}
}
public override ProcessorInfoA GetInfoIfCanProcess(string s)
{
//do something!
}
public override bool GetResult(ProcessorInfoA info, int i)
{
//do something!
}
}
public class ProcessorB : Processor<ProcessorB.ProcessorInfoB>
{
public class ProcessorInfoB : ProcessorInfo
{
public bool IsValid()
{
//do something!
}
}
public override ProcessorInfoB GetInfoIfCanProcess(string s)
{
//do something!
}
public override bool GetResult(ProcessorInfoB info, int i)
{
//do something!
}
}
我在GetProcessors方法中得到语法错误:不能隐式地将类型Play.ProcessorA
转换为Play.Processor<X>
。我怎么才能避开这个问题呢?
您正在尝试使用泛型来耦合处理器类和它的处理器信息类,这是有问题的。您最终会得到一个松散耦合,您只是将对象强制转换为它们应该是什么,而不是使泛型确保类型是正确的。
我建议您通过在类本身中存储信息来避免这个问题。运行处理器的代码不需要知道处理器使用的信息,它只需要知道处理器是否有效。
返回一个布尔值而不是一个ProcessorInfo对象,并将相关数据保存在Processor对象中。如果处理器是有效的,则它拥有所需的数据。如果没有,当您继续尝试下一个处理器时,它将与从第一步获得的数据一起消失。
解决这个问题最简单的方法是使用OfType
:
private static IEnumerable<object> GetProcessors()
{
yield return new ProcessorA();
yield return new ProcessorB();
}
public static IEnumerable<Processor<X>> GetProcessors<X>() where X: ProcessorInfo
{
return GetProcessors.OfType<Processor<X>>();
}
由于Processor<X>
是不变的,因此没有可以使用的通用类型,并且由于X
是在方法之外选择的,因此需要使用动态类型检查。