C# 自定义字典TryGetValue不';我找不到钥匙

C# 自定义字典TryGetValue不';我找不到钥匙,c#,dictionary,enums,hashcode,C#,Dictionary,Enums,Hashcode,我正在尝试创建一个基类,它的工作方式类似于状态机,可以接受任何类型的枚举: public class BaseFSM <T> where T : struct, IConvertible { //Basic class that denote the transition between one state and another public class StateTransition { public T currentStat

我正在尝试创建一个基类,它的工作方式类似于状态机,可以接受任何类型的枚举:

    public class BaseFSM <T> where T : struct, IConvertible
{

    //Basic class that denote the transition between one state and another
    public class StateTransition
    {
        public  T currentState { get; set; }
        public  T nextState { get; set; }           

        //StateTransition Constructor
        public StateTransition(T currentState, T nextState)
        {
            this.currentState = currentState;
            this.nextState = nextState;
        }

        public override int GetHashCode()
        {
            return 17 + 31 * this.currentState.GetHashCode() + 31 * this.nextState.GetHashCode();;
        }

        public override bool Equals(object obj)
        {
            StateTransition other = obj as StateTransition;
            return other != null && this.currentState as Enum == other.currentState as Enum && this.nextState as Enum == other.nextState as Enum;
        }
    }

    protected Dictionary<StateTransition, T> transitions; //All the transitions inside the FSM
    public T currentState;
    public T previusState;

    protected BaseFSM() {
        // Throw Exception on static initialization if the given type isn't an enum.
        if(!typeof (T).IsEnum) 
            throw new Exception(typeof(T).FullName + " is not an enum type.");
    }

    private T GetNext(T next)
    {
        StateTransition transition = new StateTransition(currentState, next);
        T nextState;
        if (!transitions.TryGetValue(transition, out nextState))
            throw new Exception("Invalid transition: " + currentState + " -> " + next);
        return nextState;


    }
}
公共类BaseFSM,其中T:struct,IConvertible
{
//表示一种状态和另一种状态之间转换的基本类
公共类状态转换
{
公共T当前状态{get;set;}
公共T nextState{get;set;}
//状态转换构造函数
公共状态转换(T currentState,T nextState)
{
this.currentState=currentState;
this.nextState=nextState;
}
公共覆盖int GetHashCode()
{
返回17+31*this.currentState.GetHashCode()+31*this.nextState.GetHashCode();;
}
公共覆盖布尔等于(对象对象对象)
{
StateTransformation other=对象作为StateTransformation;
返回other!=null&&this.currentState作为Enum==other.currentState作为Enum&&this.nextState作为Enum==other.nextState作为Enum;
}
}
受保护的字典转换;//FSM内的所有转换
公共财政状况;
前州政府;
受保护的BaseFSM(){
//如果给定类型不是枚举,则在静态初始化时引发异常。
if(!typeof(T).IsEnum)
抛出新异常(typeof(T).FullName+“不是枚举类型。”);
}
私人T GetNext(T next)
{
StateTransformation=新的StateTransformation(当前状态,下一个);
T下一州;
if(!transitions.TryGetValue(transition,out nextState))
抛出新异常(“无效转换:“+currentState+”->“+next”);
返回下一状态;
}
}
如您所见,我定义了GetHashCode()和Equals(objectobj)。这是我对我的孩子类的实现:

public class FSMPlayer : BaseFSM<PlayerState>
{   
    public FSMPlayer() : base()
    {           
        this.currentState = PlayerState.Idle;
        this.transitions = new Dictionary<StateTransition, PlayerState>
        {
            { new StateTransition(PlayerState.Idle, PlayerState.Run), PlayerState.Run }, //0
            { new StateTransition(PlayerState.Run, PlayerState.Jump), PlayerState.Jump }, //1
        };  
    }
}
公共类FSMPlayer:BaseFSM
{   
public FSMPlayer():base()
{           
this.currentState=PlayerState.Idle;
this.transitions=新词典
{
{新状态转换(PlayerState.Idle,PlayerState.Run),PlayerState.Run},//0
{新状态转换(PlayerState.Run,PlayerState.Jump),PlayerState.Jump},//1
};  
}
}
正如您在我的子类中看到的,我使用PlayerState枚举来定义状态转换。问题是当我尝试使用getNext函数时,因为TryGetValue总是返回false。GetHashCode的功能非常好,所以我不知道问题出在哪里。
谢谢。

您可能还需要阅读此问题的答案,以了解为什么不建议对枚举调用getHashCode

问题在于:

this.currentState as Enum == other.currentState as Enum
Enum
是一种引用类型,因此您的Enum会被装箱到一个(新的、唯一的)对象中。因此,它不再与任何其他装箱实例进行比较

enum
类型在重写
Equals
时做的事情是正确的(正如@hvd正确指出的那样),因此您只需这样做即可

this.currentState.Equals(other.currentState)

这很好。该问题的答案讨论了为什么不应依赖
GetHashCode()
返回枚举的数值。如果您实际使用它来散列它(因此根本不依赖于该属性),那就没有问题。一个简单的
this.currentState.Equals(other.currentState)
不起作用吗?@hvd:是的,当然,我很傻。(此外,枚举不实现
IComparable
,但它们实现了
IComparable
)如果您想自己发布此答案,我将删除我的答案。您确实确定了真正的问题,并且发布了有效的解决方法。我很高兴保留你的答案。:)