如何将Comparer用于HashSet

Sof*_*ter 8 c# templates dictionary hashset

由于我在这里问的另一个问题,我想为我的对象使用HashSet

我将创建包含字符串的对象和对其所有者的引用.

public class Synonym
{
   private string name;
   private Stock owner;
   public Stock(string NameSynonym, Stock stock)
   {
       name=NameSynonym;
       owner=stock
   }
   // [+ 'get' for 'name' and 'owner']
}
Run Code Online (Sandbox Code Playgroud)

我知道我需要一个比较器,但以前从未使用它.我应该创建一个单独的类吗?喜欢:

public class SynonymComparer : IComparer<Synonym>
{
   public int Compare(Synonym One, Synonym Two)
   { // Should I test if 'One == null'  or  'Two == null'  ???? 
       return String.Compare(One.Name, Two.Name, true); // Caseinsesitive
   }
Run Code Online (Sandbox Code Playgroud)

}

我更喜欢有一个函数(或嵌套类[可能是单例?],如果需要)作为类同义词的PART而不是另一个(独立)类.这可能吗?

关于用法:因为我之前从未使用过这种东西,我想我必须在类同义词中写一个Find(字符串NameSynonym)函数,但是我应该怎么做呢?

public class SynonymManager
{ 
    private HashSet<SynonymComparer<Synonym>> ListOfSynonyms;

    public SynonymManager()
    {
        ListOfSymnonyms = new HashSet<SynonymComparer<Synonym>>();
    }

    public void SomeFunction()
    { // Just a function to add 2 sysnonyms to 1 stock
        Stock stock = GetStock("General Motors");
        Synonym otherName = new Synonym("GM", stock);
        ListOfSynonyms.Add(otherName);
        Synonym otherName = new Synonym("Gen. Motors", stock);
        ListOfSynonyms.Add(otherName);
    }

    public Synonym Find(string NameSynomym)
    {
       return ListOfSynonyms.??????(NameSynonym);
    }
 }
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我不知道如何实现'Find'方法.我该怎么做?

任何帮助将不胜感激(PS如果我的想法应该如何实现完全错误让我知道并告诉我如何实现)

Jon*_*eet 16

HashSet不需要IComparer<T>- 它需要一个IEqualityComparer<T>,例如

public class SynonymComparer : IEqualityComparer<Synonym>      
{
   public bool Equals(Synonym one, Synonym two)
   {
        // Adjust according to requirements.
        return StringComparer.InvariantCultureIgnoreCase
                             .Equals(one.Name, two.Name);

   }

   public int GetHashCode(Synonym item)
   {
        return StringComparer.InvariantCultureIgnoreCase
                             .GetHashCode(item.Name);

   }
}
Run Code Online (Sandbox Code Playgroud)

但是,您当前的代码只会编译,因为您创建的是一组比较器而不是一组同义词.

此外,我认为你根本不想要一套.在我看来,你想要一个字典或查找,以便你可以找到给定名称的同义词:

public class SynonymManager
{ 
    private readonly IDictionary<string, Synonym> synonyms = new
        Dictionary<string, Synonym>();

    private void Add(Synonym synonym)
    {
        // This will overwrite any existing synonym with the same name.
        synonyms[synonym.Name] = synonym;
    }

    public void SomeFunction()
    { 
        // Just a function to add 2 synonyms to 1 stock.
        Stock stock = GetStock("General Motors");
        Synonym otherName = new Synonym("GM", stock);
        Add(otherName);
        ListOfSynonyms.Add(otherName);
        otherName = new Synonym("Gen. Motors", stock);
        Add(otherName);
    }

    public Synonym Find(string nameSynonym)
    {
       // This will throw an exception if you don't have
       // a synonym of the right name.  Do you want that?
       return synonyms[nameSynonym];
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,上面的代码中有一些问题,关于您希望它在各种情况下的行为方式.你需要准确地计算出你想要它做的事情.

编辑:如果你想能够为一个同义词存储多个股票,你实际上想要一个Lookup<string, Stock>- 但这是不可改变的.你可能最好存储一个Dictionary<string, List<Stock>>; 每个字符串的股票清单.

在不引发错误的方面Find,你应该看看Dictionary.TryGetValue不抛出一个异常关键是没有找到(和返回键是否找到); 映射值在out参数中"返回".

  • @ilya:Dictionary <,>一直使用哈希表方法 - 但它不在内部使用HashSet.基本上两种类型都使用相同的概念(散列),但它们提供不同的接口 - 一组只是具有项是否在集合中的概念,而字典将键映射到值.只需忽略该值,您就可以轻松实现给定字典的HashSet - 从HashSet构建Dictionary更加困难. (2认同)