C# 带对象键的字典
我正在努力使用一个特定的字典来改变一个对象的状态 我的想法是,我有一个类进程,它是每次用户提交要处理的内容时创建的。进程具有ID、一些其他信息和当前状态。可能的CurrentState在StateEnum类中定义,包含“挂起、处理、完成、错误”等状态。 之后,用户可以执行一些任务/命令——每个任务也被定义为一个类,并包含进程ID和执行方法ID,从而更改对象的状态。这些任务从接口ITask继承 问题是,我需要某种状态机,它将验证是否可以使用任务“ResumeTask”从状态“Pending”移动到状态“Processing”。为了进行此验证,我使用字典创建了类状态,并且每次创建进程时都会创建其对象 问题是,这本词典不能正常使用。让我用一些注释展示代码(我创建了简单的控制台应用程序只是为了演示问题),并解释发生了什么: ITask接口C# 带对象键的字典,c#,.net,dictionary,C#,.net,Dictionary,我正在努力使用一个特定的字典来改变一个对象的状态 我的想法是,我有一个类进程,它是每次用户提交要处理的内容时创建的。进程具有ID、一些其他信息和当前状态。可能的CurrentState在StateEnum类中定义,包含“挂起、处理、完成、错误”等状态。 之后,用户可以执行一些任务/命令——每个任务也被定义为一个类,并包含进程ID和执行方法ID,从而更改对象的状态。这些任务从接口ITask继承 问题是,我需要某种状态机,它将验证是否可以使用任务“ResumeTask”从状态“Pending”移动到
public interface ITask
{
int IntParam1 { get; set; }
void Execute(Process proc);
}
ResumeTask类(我还有暂停任务和其他任务)
过程类
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;
}
}
}
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();
}
}
国家级
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;
}
}
}
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();
}
}
程序类
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;
}
}
}
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();
}
}
让我们快速浏览一些要点:
可用的任务
它工作得很好-我在MoveNext方法中检查了它们,并且能够进行有效的移动-问题是,使用这种方法,我无法创建场景,在这种场景中,我需要为一个状态提供多个任务编辑: 如果我将其余部分保持原样,只需像这样更改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;
}
}
}
类状态
{
公共状态枚举当前状态;
词典转换;
ITask pause=新的PauseTask();
ITask resume=新的ResumeTask();
公共国家()
{
CurrentState=StateEnum.Pending;
转换=新字典
{
{暂停,StateEnum.Pending},
{resume,StateEnum.Processing}
};
}
公共状态枚举移动下一步(ITask任务)
{
statenum nextState;
if(!transitions.TryGetValue(任务,out nextState))
{
返回StateEnum.Error;
}
其他的
{
返回下一状态;
}
}
}
它正在工作-如果状态为StateEnum.Pending,并且我在MoveNext()方法中传递task ResumeTask ResumeTask=new ResumeTask(),它将返回我StateEnum.Processing,这是正确的
所以“简单”对象键字典正在工作,但是当我将该对象封装到另一个对象中时,尽管再次重写Equals和GetHashCode,我还是无法获得匹配项(该实现显示在主post-State类中)
问题是,如果我基本上是传递同一类的对象,为什么我不能得到匹配
EDIT2: 这对于我所需要的目的来说太复杂了。我尝试了使用
List
的不同方法,因为创建字典后我不需要更改它,而且List对于更多值使用相同的键没有问题。到目前为止,它正在发挥作用
如果需要,我可以发布最终的代码。在其他情况下缩小您的问题这对我来说是“太宽泛的问题”,我不知道您的确切意思,但基本上我不明白,为什么要使用“简单”对象键字典