Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何包含一个";“小丑”;哈希代码中的值_C#_.net_Gethashcode - Fatal编程技术网

C# 如何包含一个";“小丑”;哈希代码中的值

C# 如何包含一个";“小丑”;哈希代码中的值,c#,.net,gethashcode,C#,.net,Gethashcode,我有以下示例类: public sealed class MyDictKey { public int Type { get; } public int SubType { get; } public MyDictKey(int type, int subType) // both can only be positive values { Type = type; SubType = subType; } pu

我有以下示例类:

public sealed class MyDictKey
{
    public int Type { get; }
    public int SubType { get; }

    public MyDictKey(int type, int subType) // both can only be positive values
    {
        Type = type;
        SubType = subType;
    }

    public override bool Equals(object obj)
    {
        if (obj is MyDictKey other)
        {
            bool typeEqual = other.Type == Type;
            bool subTypeEqual = other.SubType == -1 || SubType == -1 || other.SubType == SubType;
            return typeEqual && subTypeEqual;
        }

        return false;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;
            hash = hash * 23 + Type.GetHashCode();
            return hash;
        }
    }
}
以及以下测试(NUnit,如果有人感兴趣):

[测试]
公共无效计算器测试()
{
Dictionary myTypeProcessors=新字典();
添加(新的MyDictKey(10,20),“10.20_处理器”);
添加(新的MyDictKey(3,4),“3.4_处理器”);
添加(新的MyDictKey(4,-1),“4.任何处理器”);
//-1表示它可以处理“任何”子类型
for(int i=0;i<1000;i++)//应适用于任何正数
{
bool canGet=myTypeProcessors.TryGetValue(新的MyDictKey(4,i),输出字符串值);
断言。IsTrue(canGet);
断言(值,即.EqualTo(“4.任何处理器”);
bool canGet2=myTypeProcessors.TryGetValue(新的MyDictKey(10,i),输出字符串值2);
如果(i==20)
{
断言IsTrue(canGet2);
断言(value2,即.EqualTo(“10.20_处理器”);
}
其他的
{
Assert.IsFalse(canGet2);
}
}
}
我能否仅通过使用GetHashCode以某种方式达到相同的机制?因为这样,如果只有子类型不同,字典的TryGetValue将始终调用Equals方法。重要的是,新方法不得比原始方法慢

我想到的是位运算符;或者有什么神奇的数学公式


提前谢谢。

这甚至不是一个定义良好的等式函数,因为它不能传递

例如A=(1,1),B=(1,-1),C=(1,2)

A=B,B=C,但不是A=C

考虑:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

    namespace ConsoleApp5
    {
        class Program
        {
            static void Main(string[] args)
            {
                var A = new MyDictKey(1, 1);
                var B = new MyDictKey(1, -1);
                var C = new MyDictKey(1, 2);

                var h = new HashSet<MyDictKey>();
                h.Add(A);
                h.Add(B);
                h.Add(C);
                Console.WriteLine(h.Count); //outputs 2


                var h2 = new HashSet<MyDictKey>();
                h2.Add(B);
                h2.Add(C);
                h2.Add(A);
                Console.WriteLine(h2.Count); //outputs 1

                Console.ReadKey();

            }

            public sealed class MyDictKey
            {
                public int Type { get; }
                public int SubType { get; }

                public MyDictKey(int type, int subType) // both can only be positive values
                {
                    Type = type;
                    SubType = subType;
                }

                public override bool Equals(object obj)
                {
                    if (obj is MyDictKey other)
                    {
                        bool typeEqual = other.Type == Type;
                        bool subTypeEqual = other.SubType == -1 || SubType == -1 || other.SubType == SubType;
                        return typeEqual && subTypeEqual;
                    }

                    return false;
                }

                public override int GetHashCode()
                {
                    unchecked
                    {
                        int hash = 17;
                        hash = hash * 23 + Type.GetHashCode();
                        return hash;
                    }
                }
            }
        }
    }
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间控制台EAPP5
{
班级计划
{
静态void Main(字符串[]参数)
{
var A=新的MyDictKey(1,1);
var B=新的MyDictKey(1,-1);
var C=新的MyDictKey(1,2);
var h=新的HashSet();
h、 添加(A);
h、 添加(B);
h、 添加(C);
Console.WriteLine(h.Count);//输出2
var h2=新的HashSet();
h2.添加(B);
h2.添加(C);
h2.添加(A);
Console.WriteLine(h2.Count);//输出1
Console.ReadKey();
}
公共密封类密钥
{
公共int类型{get;}
公共int子类型{get;}
public MyDictKey(int类型,int子类型)//两者只能是正值
{
类型=类型;
亚型=亚型;
}
公共覆盖布尔等于(对象对象对象)
{
如果(obj是MyDictKey其他)
{
bool typeEqual=other.Type==Type;
bool SubType equal=other.SubType==-1 | | SubType==-1 | | other.SubType==SubType;
返回typeEqual&子类型equal;
}
返回false;
}
公共覆盖int GetHashCode()
{
未经检查
{
int hash=17;
hash=hash*23+Type.GetHashCode();
返回散列;
}
}
}
}
}

您可以让GetHashCode返回您想要的任何内容,例如,
使用标准字典无法键入,但如果您使用自定义哈希代码比较进行自定义实现,则可以。但要小心,应该使用joker second类型向所有具有相同主类型散列的bucket添加值。如果你做这个实验,请提供一个结果,它将非常感激你是对的。我知道这一点,但这正是我想要的工作方式。你还有其他建议吗?@KárolyOzsvárt:Dictionary类需要一个可传递的Equals方法。MyDictKey.Equals方法是不可传递的(不能定义一个在某些时候忽略成员的Equals方法),因此不能将该类用作字典键。如果您希望它以不同的方式工作,那么实现您自己的查找逻辑,而不是使用字典。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

    namespace ConsoleApp5
    {
        class Program
        {
            static void Main(string[] args)
            {
                var A = new MyDictKey(1, 1);
                var B = new MyDictKey(1, -1);
                var C = new MyDictKey(1, 2);

                var h = new HashSet<MyDictKey>();
                h.Add(A);
                h.Add(B);
                h.Add(C);
                Console.WriteLine(h.Count); //outputs 2


                var h2 = new HashSet<MyDictKey>();
                h2.Add(B);
                h2.Add(C);
                h2.Add(A);
                Console.WriteLine(h2.Count); //outputs 1

                Console.ReadKey();

            }

            public sealed class MyDictKey
            {
                public int Type { get; }
                public int SubType { get; }

                public MyDictKey(int type, int subType) // both can only be positive values
                {
                    Type = type;
                    SubType = subType;
                }

                public override bool Equals(object obj)
                {
                    if (obj is MyDictKey other)
                    {
                        bool typeEqual = other.Type == Type;
                        bool subTypeEqual = other.SubType == -1 || SubType == -1 || other.SubType == SubType;
                        return typeEqual && subTypeEqual;
                    }

                    return false;
                }

                public override int GetHashCode()
                {
                    unchecked
                    {
                        int hash = 17;
                        hash = hash * 23 + Type.GetHashCode();
                        return hash;
                    }
                }
            }
        }
    }