获取字典中接口的重复条目

佩德罗·科斯塔(Pedro Costa)

所以我有一个命名为接口的接口IResource该接口由这5个属性组成为只读,但是由于我将这些属性添加到a中,因此Dictionary<IResource, int>我需要一种比较两个属性的方法,IResource因此在Dictionary中没有重复项。有没有办法为Equals(object obj)每个IResource添加默认值我已经EqualsWood类中添加了Override ,它解决了问题,但是我必须Equals(object obj)在实现的每个类中添加一个IResource

public class Wood : IResource
{
    public string Package => "Core";

    public string Family => "Wood";

    public string Name => "Wood";

    public bool IsFractal => false;

    public ResourceType Type => ResourceType.Natural;
}

PS:我Add(IResource key, uint value)对字典有一个方法重写,以检查是否IResource已经存在。

    public new void Add(IResource key, uint value)
    {
        if (base.ContainsKey(key))
            base[key] += value;
        else
            base.Add(key, value);
    }

现在,当我IResource向字典添加接口时,它总是会添加一个新条目。

迈克

正如其他人指出的那样,虽然有可能创建一个抽象基类,但这并不是一个好主意。您正在创建一个依赖关系,任何实现IResource的类也必须实现相等性,就像为IResource定义它一样。那可能很好,或者可能很难维护并导致错误。

该框架旨在通过允许您自定义词典进行比较的方式来处理这种情况。它通过使用IEqualityComparer做到这一点。

这是您的IResource接口的示例:

public class ResourceComparer : IEqualityComparer<IResource>
{
    public bool Equals([AllowNull] IResource x, [AllowNull] IResource y)
    {
        if (null == x && null == y)
            return true;

        if (null == x || null == y)
            return false;

        return x.Package.Equals(y.Package) &&
            x.Family.Equals(y.Family) &&
            x.Name.Equals(y.Name) &&
            x.IsFractal.Equals(y.IsFractal) &&
            x.Type.Equals(y.Type);
    }

    public int GetHashCode([DisallowNull] IResource obj)
    {
        HashCode hash = new HashCode();
        hash.Add(obj.Package);
        hash.Add(obj.Family);
        hash.Add(obj.Name);
        hash.Add(obj.IsFractal);
        hash.Add(obj.Type);
        return hash.ToHashCode();
    }
}

一旦知道了,就可以使用该比较器创建字典。我用过您的Wood类并创建了另一个名为Metal的类。既不必共享基类,也不必重写Equals和GetHashCode。

    static void Main(string[] _)
    {
        var resourceMap = new Dictionary<IResource,uint>(new ResourceComparer());

        var resources = new IResource[] { new Wood(), new Metal(), 
                                         new Wood(), new Wood() };

        foreach (var r in resources)
        {
            if (resourceMap.TryGetValue(r, out var count))
                resourceMap[r] = count + 1;
            else
                resourceMap.Add(r, 1);
        }

        Console.WriteLine(resourceMap[new Wood()]);
        Console.WriteLine(resourceMap[new Metal()]);
    }

这是简单的POCO风格的金属类:

public class Metal : IResource
{
    public string Package => "Core";

    public string Family => "Metal";

    public string Name => "Metal";

    public bool IsFractal => false;

    public ResourceType Type => ResourceType.ManMade;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章