如何创建类似 HashSet 的数据结构?

huangapple go评论88阅读模式
英文:

How to create Data structure like HashSet?

问题

创建一个类似于HashSet但存储不同类型而不是值的数据结构的最佳方法是什么?

如何简化这段代码,我觉得我做错了什么,遍历整个列表似乎是不必要的。

我拥有的示例代码如下:

  1. public abstract class Foo {}
  2. public class FooA : Foo {}
  3. public class FooB : Foo {}
  4. public class FooList : List<Foo>
  5. {
  6. public new void Add(Foo fooItem)
  7. {
  8. // 在不遍历的情况下进行处理
  9. foreach (var item in this)
  10. {
  11. if (item.GetType() == fooItem.GetType())
  12. return;
  13. }
  14. base.Add(fooItem);
  15. }
  16. }

这是它的用法:

  1. FooA fooA = new FooA();
  2. FooB fooB = new FooB();
  3. FooB anotherFooB = new FooB();
  4. FooList list = new FooList();
  5. list.Add(fooA);
  6. list.Add(fooB);
  7. list.Add(anotherFooB);
  8. foreach(var item in list)
  9. {
  10. Console.WriteLine(item);
  11. }
  12. /* 输出:
  13. FooA
  14. FooB
  15. */
英文:

What is the best way to make a data structure similar to HashSet but unique types instead of values.

How can I simplify this code, it seems to me that I'm doing something wrong and going through the whole list is unnecessary.

An example of what I have:

  1. public abstract class Foo {}
  2. public class FooA : Foo {}
  3. public class FooB : Foo {}
  4. public class FooList : List&lt;Foo&gt;
  5. {
  6. public new void Add(Foo fooItem)
  7. {
  8. // как то без перебора
  9. foreach (var item in this)
  10. {
  11. if (item.GetType() == fooItem.GetType())
  12. return;
  13. }
  14. base.Add(fooItem);
  15. }
  16. }

This is how it is used:

  1. FooA fooA = new FooA();
  2. FooB fooB = new FooB();
  3. FooB anotherFooB = new FooB();
  4. FooList list = new FooList();
  5. list.Add(fooA);
  6. list.Add(fooB);
  7. list.Add(anotherFooB);
  8. foreach(var item in list)
  9. {
  10. Console.WriteLine(item);
  11. }
  12. /* Output:
  13. FooA
  14. FooB
  15. */

答案1

得分: 1

你可以使用 HashSet&lt;Type&gt;,例如。

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. ...
  5. public class FooList : IEnumerable&lt;Type&gt; {
  6. private HashSet&lt;Type&gt; m_Types = new HashSet&lt;Type&gt;();
  7. public bool Add(object value) =&gt; value is null
  8. ? false
  9. : m_Types.Add(value.GetType());
  10. public IEnumerator&lt;Type&gt; GetEnumerator() =&gt; m_Types.GetEnumerator();
  11. IEnumerator IEnumerable.GetEnumerator() =&gt; m_Types.GetEnumerator();
  12. }

然后你可以使用你的代码:

  1. FooA fooA = new FooA();
  2. FooB fooB = new FooB();
  3. FooB anotherFooB = new FooB();
  4. FooList list = new FooList();
  5. list.Add(fooA);
  6. list.Add(fooB);
  7. list.Add(anotherFooB);
  8. foreach(var item in list)
  9. {
  10. Console.WriteLine(item);
  11. }

并得到预期输出:

  1. FooA
  2. FooB

Fiddle

英文:

You can use HashSet&lt;Type&gt;, e.g.

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. ...
  5. public class FooList : IEnumerable&lt;Type&gt; {
  6. private HashSet&lt;Type&gt; m_Types = new HashSet&lt;Type&gt;();
  7. public bool Add(object value) =&gt; value is null
  8. ? false
  9. : m_Types.Add(value.GetType());
  10. public IEnumerator&lt;Type&gt; GetEnumerator() =&gt; m_Types.GetEnumerator();
  11. IEnumerator IEnumerable.GetEnumerator() =&gt; m_Types.GetEnumerator();
  12. }

Then you can use your code:

  1. FooA fooA = new FooA();
  2. FooB fooB = new FooB();
  3. FooB anotherFooB = new FooB();
  4. FooList list = new FooList();
  5. list.Add(fooA);
  6. list.Add(fooB);
  7. list.Add(anotherFooB);
  8. foreach(var item in list)
  9. {
  10. Console.WriteLine(item);
  11. }

And get expected output:

  1. FooA
  2. FooB

Fiddle

huangapple
  • 本文由 发表于 2023年5月30日 02:46:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76359701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定