我正在努力使用特定字典来改变对象的状态。
我的想法是我有类Process,每次用户提交要处理的东西时都会创建。进程有ID,其他一些信息和CurrentState。可能的CurrentStates在StateEnum类中定义,包含" Pending,Processing,Completed,Error"等状态。等等 之后,有一些任务/命令,用户可以执行 - 每个任务都被定义为一个类,并包含进程ID和Execute方法,它们改变了对象的状态。这些任务继承自ITask接口。
事情是,我需要某种状态机,这将验证是否可以从状态" Pending"陈述"处理"使用任务" ResumeTask"例如。对于此验证,我使用字典创建了类State,并且每次创建Process时都会创建其对象。
问题是,字典无法正常工作。让我展示代码(我创建简单的控制台应用程序只是为了演示问题),并提供一些注释并解释发生了什么:
ITask界面
public interface ITask
{
int IntParam1 { get; set; }
void Execute(Process proc);
}
ResumeTask类(我还有PauseTask和其他任务)
class ResumeTask : ITask
{
int intParam1;
public int IntParam1
{
get { return intParam1; }
set { intParam1 = value; }
}
public void Execute(Process proc)
{
ResumeTask resume = new ResumeTask();
proc.ChangeState(resume);
//code below not working - is there a way how to make this
//work instead of creating new empty class above?
//proc.ChangeState(this);
}
public override int GetHashCode()
{
return 17 + 31 * intParam1.GetHashCode();
}
public override bool Equals(object obj)
{
ResumeTask other = obj as ResumeTask;
return other != null && this.intParam1 == other.intParam1;
}
}
流程类
public class Process
{
State stat;
private int processID;
public int ProcessID
{
get { return processID; }
private set { processID = value; }
}
private StateEnum state;
public StateEnum State
{
get { return state; }
set { state = value; }
}
public readonly int userID;
public int UserID
{
get { return userID; }
}
public Process(int processID, int userID)
{
this.processID = processID;
this.userID = userID;
stat = new State();
this.state = stat.CurrentState;
}
public void ChangeState(ITask task)
{
this.state = stat.MoveNext(task);
}
}
州级
class State
{
private class StateTransition
{
public StateEnum State;
public ITask Task;
public StateTransition(StateEnum state, ITask task)
{
State = state;
Task = task;
}
public override int GetHashCode()
{
return 17 + 31 * State.GetHashCode() + 31 * Task.GetHashCode();
}
public override bool Equals(object obj)
{
StateTransition other = obj as StateTransition;
return other != null && this.State == other.State && this.Task == other.Task;
}
}
public StateEnum CurrentState;
Dictionary<StateTransition, StateEnum> transitions;
ITask pause = new PauseTask();
ITask resume = new ResumeTask();
ITask resumenew = new ResumeTask();
public State()
{
CurrentState = StateEnum.Pending;
transitions = new Dictionary<StateTransition, StateEnum>
{
{ new StateTransition(StateEnum.Processing, pause), StateEnum.Pending },
{ new StateTransition(StateEnum.Pending, resume), StateEnum.Processing }
};
}
public StateEnum MoveNext(ITask task)
{
StateTransition transition = new StateTransition(CurrentState, task);
StateEnum nextState;
if (!transitions.TryGetValue(transition, out nextState))
{
return StateEnum.Error;
}
else
{
return nextState;
}
}
}
StateEnum枚举
public enum StateEnum
{
Pending,
Processing,
Error,
Processed,
Downloaded
}
计划类
class Program
{
static void Main(string[] args)
{
Process proc = new Process(1, 20);
ResumeTask resumetask = new ResumeTask();
resumetask.IntParam1 = 1;
resumetask.Execute(proc);
Console.WriteLine(Convert.ToString(proc.ProcessState));
Console.ReadLine();
}
}
让我们快速浏览一些重点:
我尝试了几件事 - 我试图创建两个简单的词典:
跃迁<ITask, StateEnum>
;
availableTasks <StateEnum,ITask>
;
并且工作正常 - 我在MoveNext方法中检查了它们并且能够进行有效移动 - 问题是,通过这种方法,我无法创建场景,其中我需要为1个状态提供多个任务
StateTransition transition = new StateTransition(CurrentState,task);
在State类的MoveNext方法中 - 例如,如果我放置对象&#34; resume&#34; (之前创建的是为了将其添加到字典中)而不是&#34; task&#34;参数,它正在工作 - 因为我基本比较了2个相同的对象。但是,正如您所看到的,我还尝试定义对象
ITask resumenew = new ResumeTask();
再次传递而不是&#34;任务&#34;参数 - 它无法正常工作。
总结一下 - 这是一种非常糟糕的做法,还是我某处有一些小错误,我不知道? 我希望这个问题不会太混乱 - 如果有任何问题,我可以编辑或回答评论。谢谢你的帮助。
修改 如果我按原样保留其余部分,只需更改State类:
class State
{
public StateEnum CurrentState;
Dictionary<ITask, StateEnum> transitions;
ITask pause = new PauseTask();
ITask resume = new ResumeTask();
public State()
{
CurrentState = StateEnum.Pending;
transitions = new Dictionary<ITask, StateEnum>
{
{pause, StateEnum.Pending },
{resume, StateEnum.Processing }
};
}
public StateEnum MoveNext(ITask task)
{
StateEnum nextState;
if (!transitions.TryGetValue(task, out nextState))
{
return StateEnum.Error;
}
else
{
return nextState;
}
}
}
它正在工作 - 如果state是StateEnum.Pending并且我在MoveNext()方法中传递任务ResumeTask resumetask = new ResumeTask(),它将返回StateEnum.Processing,这是正确的。
所以&#34;简单&#34;对象键字典正在工作,但是当我将该对象封装到另一个对象中时,尽管再次覆盖了Equals和GetHashCode,但我无法获得匹配(该实现显示在主post-State类中)。
问题是,如果我基本上传递同一类的对象,为什么我不能得到匹配。
EDIT2:
这对于我需要的目的来说太复杂了。我尝试了使用List<KeyValuePair<Enum,Object>>
的不同方法,因为我不需要在创建字典后更改字典,并且列表对于更多值没有相同键的问题。到目前为止,它正在发挥作用。
如果需要,我可以发布最终代码。