所以我有一个命名为接口的接口IResource
,该接口由这5个属性组成为只读,但是由于我将这些属性添加到a中,因此Dictionary<IResource, int>
我需要一种比较两个属性的方法,IResource
因此在Dictionary中没有重复项。有没有办法为Equals(object obj)
每个IResource添加默认值?我已经Equals
在Wood
类中添加了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] 删除。
我来说两句