C# 如何根据项目在树中的位置为类似树的数据结构编写哈希代码?

C# 如何根据项目在树中的位置为类似树的数据结构编写哈希代码?,c#,.net,hash,tree,gethashcode,C#,.net,Hash,Tree,Gethashcode,每个项目如下所示: public interface IEffect { string Name { get; } bool Compute ( ); List<IEffect> SubEffects { get; set; } IEffect ElseIfEffect { get; set; } } 公共接口效果 { 字符串名称{get;} boolcompute(); 列表子效果{get;set;} IEffect elseifefect{ge

每个项目如下所示:

public interface IEffect
{
    string Name { get; }
    bool Compute ( );

    List<IEffect> SubEffects { get; set; }
    IEffect ElseIfEffect { get; set; }
}
公共接口效果
{
字符串名称{get;}
boolcompute();
列表子效果{get;set;}
IEffect elseifefect{get;set;}
}
我想创建一个树状结构,使用这些项目的许多实例相互连接,形成一个树状结构。但是后来我想将每个项目散列到一个字典中,所以我想如果我可以根据它们在树上的位置创建一个散列值,那么我可以得到足够唯一的散列值


关于如何做到这一点,有什么想法吗?

从我的评论中抄袭,每个评论:)。为什么需要散列值?简单使用默认的对象哈希函数有什么错?如果这是一个完整的二叉树,您可以将节点映射到整数值,但是对于任意的n元树,我看不到将位置编码为值的简单方法

基于它们在树上的位置

该信息不是节点的一部分,而是树的一部分。因此,这将是一个非常糟糕的想法(定义一些关于外部因素的HashCode)


幸运的是,正如@spintheblack指出的,这里绝对没有理由重写GethashCode()

实现接口IEffect的每个项都应该覆盖ToString&GetHashCode

ToString应包含IEffect属性的唯一状态,包括选定值 GetHashCode应该是ToString()。GetHashCode()


根据对象内部数据,每个对象都有一个唯一的散列。

这应该可以做到。警告:不要用此方法重写GetHashCode。GetHashCode不应突变,因为父实体中的对象位置已更改。只有当您对哈希代码有其他计划时,才使用此技巧。这是一个大致的例子,你应该按照你的要求去做。这仅显示如何找到当前父对象的位置,但可以将其扩展到遍历树,直到没有父对象为止

class MyEffect : IEffect
{
    IEffect _owner;
    public MyEffect(IEffect owner) 
    {
        _owner = owner;
    }

    public int GetFunkyHash()
    {
        int hash = this.GetHashCode();
        int index = _owner.IndexOf(item);
        return hash | index.GetHashCode();
    }
}

以下是我是如何做到我认为你真正需要做的事情的。这将遍历整个树的处理效果。不需要链接到父节点,除非你需要从树中间开始。当然,这只是我对你可能要做的事情的疯狂解释

public void HandleEffects(IEffect effect)
{
    if(effect.Compute())
        foreach(IEffect child in effect.SubEffects)
            HandleEffects(child);

    else
        HandleEffect(effect.ElseEffect);
}

为什么需要散列值?简单使用默认的对象哈希函数有什么错?如果这是一个完整的二叉树,您可以将节点映射到整数值,但是对于任意的n元树,我看不到将位置编码为值的简单方法。谢谢,解决哈希代码的需要基本上就是这样。此树将在运行时定义(可自定义)。当执行某个操作时,我想查看该操作当前是哪个分支/叶,并基于该值,从字典中查找下一步要做什么。因此,基于此树中的位置,相同的操作将执行不同的操作。所以对于leaf-a,这可以是delete,但是对于leaf-b,它可以是remove,例如。这有意义吗?@Joan:用HasCode解决这个问题没有意义。您似乎需要一个back引用,比如
IEffect parent
属性。@Henk:谢谢,我正考虑为此添加一个parent属性。但是如果不使用该属性进行散列,我将如何处理该属性?我认为您可以使用它“查看当前操作是哪个分支/叶”。避免对可变类型使用hashcode(并且您的节点和树都是可变的)。这是一个可能的答案,但和其他人一样,我认为这不是一个好主意。也许你可以解释一下为什么你想创建自己的哈希函数,这样我们就可以更好地理解你的需求。谢谢,我添加了更多的信息问题的评论。另外,您能告诉我“int index…”这行代码是做什么的吗?这行代码使用Linq扩展方法在所有者的SubEffects集合中查找“this”的索引。@chill:如果插入/删除了项怎么办?@Henk:如果哈希值在集合中的位置发生变化,它将发生变化。这是为什么不应该用来覆盖GethashCode的原因之一