我正在尝试设计一种模式来协调多个操作。每个操作都会接受一个参数并传递一个结果。该结果可能会或可能不会被以下操作使用。这是设计的简化版本,但是如果您将其复制/粘贴到控制台项目上,它将“工作”(有一个我无法修复的编译错误)。
错误
类型“ConsoleApplication1.InternalDebit”不能用作泛型类型或方法“ConsoleApplication1.Orchestrator.Add(T1)”中的类型参数“T1”。没有从“ConsoleApplication1.InternalDebit”到“ConsoleApplication1.Operation”的隐式引用转换。c:\projects\BCP\BaseMvc\ConsoleApplication1\ConsoleApplication1\Program.cs 17 13 ConsoleApplication1
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var internalDebit = new InternalDebit<InternalDebitParameter, InterbankCreditParameter>(new InternalDebitParameter() { Id = 1 });
var orchestrator = new Orchestrator();
// error here!
orchestrator.Add(internalDebit);
}
}
public interface IParameter
{
}
public interface IResult
{
}
public interface IReversible
{
void Reverse();
}
public interface IOperation<T, R>
where T : class, IParameter
where R : class, IResult
{
Type ParameterType { get; }
Type ResultType { get; }
T Parameter { get; set; }
R Execute(T parameter);
}
public abstract class Operation<T, R> : IOperation<T, R>
where T : class, IParameter
where R : class, IResult
{
public virtual R Execute(T parameter)
{
this.Parameter = parameter;
return default(R);
}
public Type ParameterType
{
get { return typeof(T); }
}
public Type ResultType
{
get { return typeof(R); }
}
public T Parameter { get; set; }
public Operation(T parameter)
{
this.Parameter = parameter;
}
}
public class InternalDebitParameter : IParameter
{
public int Id { get; set; }
}
public class InterbankCreditParameter : IParameter, IResult
{
public int Id { get; set; }
}
public class InternalDebit<T, R> : Operation<T, R>
where T : class, IParameter
where R : class, IResult
{
public InternalDebit(T parameter)
: base(parameter)
{
}
public override R Execute(T parameter)
{
return new InterbankCreditParameter() { Id = 2 } as R;
}
}
public class Orchestrator
{
public List<Operation<IParameter, IResult>> Operations { get; private set; }
public List<IParameter> Parameters { get; private set; }
public void Add<T1>(T1 t) where T1 : Operation<IParameter, IResult>
{
this.Operations.Add(t);
}
public void SetUpParameters(params IParameter[] parameters)
{
this.Parameters = new List<IParameter>();
parameters.ToList().ForEach(s => this.Parameters.Add(s));
}
public void Play()
{
IParameter generalResult = null;
foreach (var instrument in this.Operations)
{
var parameter = this.Parameters.FirstOrDefault(s => s.GetType() == instrument.ParameterType);
if (parameter == null)
{
IResult actualResult = null;
if (generalResult != null)
{
try
{
actualResult = instrument.Execute(generalResult);
}
catch (Exception ex)
{
if (instrument is IReversible)
((IReversible)instrument).Reverse();
else
throw;
break;
}
finally
{
if (actualResult is IParameter)
generalResult = (IParameter)actualResult;
}
}
else
{
throw new Exception("Orchetrator missconfiguration.");
}
}
}
}
}
}