HashSet与自定义对象相等并获取一个元素

时间:2014-09-23 11:00:29

标签: c#

我有以下类和它的HashSet:

public class VersionSettings {
  public String Culture { get; set; }
  public String Domain { get; set; }
  public String Name { get; set; }    
}

HashSet<VersionSetting> vs = ...

问题

  1. 我希望当Culture相同时,两个VersionSettings是相同的。

    在这一刻,事情并非如此。我该如何解决这个问题?

  2. 可以使用以下方法从HashSet获取VersionSetting:

    var b = vs [“en-US”];

    也许使用一些HashSet扩展名?

2 个答案:

答案 0 :(得分:2)

您可以覆盖EqualsGetHashCode,不仅可以比较Object.Equals所做的参考:

public class VersionSettings
{
    public String Culture { get; set; }
    public String Domain { get; set; }
    public String Name { get; set; }

    public override bool Equals(object obj)
    {
        VersionSettings other = obj as VersionSettings;
        if(other == null) return false;
        return Culture == other.Culture;
    }

    public override int GetHashCode()
    {
        return Culture == null ? 0 : Culture.GetHashCode();
    }
}

另一种方法是实现一个自定义IEqualityComparer<VersionSettings>,它不需要修改类本身:

public class VersionSettingComparer : IEqualityComparer<VersionSettings>
{
    public bool Equals(VersionSettings x, VersionSettings y)
    {
        if (x == null && y == null) return true;
        if (x == null || y == null) return false;
        return x.Culture == y.Culture;
    }

    public int GetHashCode(VersionSettings obj)
    {
        if(obj == null) return 0;
        return obj.Culture == null ? 0 : obj.Culture.GetHashCode();
    }
}

现在您可以使用HashSet<T>的构造函数:

var vs = new HashSet<VersionSettings>(new VersionSettingComparer());

根据您的第二个问题,您如何以这种方式访问​​HashSet<VersionSetting>

var enUsSetting = vs["en-US"];

这不起作用,因为hashset没有像集合或字典那样的索引器。您可能需要Dictionary<string, VersionSettings>代替。

简单但不是那么有效的解决方法,您可以使用LINQ:

var enUsSetting = vs.FirstOrDefault(x => x.Culture == "en-US");

如果你想创建上面提到的字典,你也可以使用LINQ:

Dictionary<string, VersionSettings> cultureLoookup = vs
    .ToDictionary(x => x.Culture, x => x);  // you only need to create this once

现在可行:

var enUsSetting = cultureLoookup["en-US"];

答案 1 :(得分:0)

为什么以简单的方式不使用Dictionary<string, VersionSettings>。例如:

var settings = new Dictionary<string, VersionSettings>();
settings["en-US"] = usSettings;   
settings["es-ES"] = esSettings;
...
var currentSetting = settings[currentSettingIdText];

这只是一个提示。