C#3。0 集合

简介: 实现IEnumerable伴随一个迭代: public class MyGenCollection : IEnumerable{ int[] data = {1, 2, 3}; public IEnumerator GetEnume...

实现IEnumerable<T>伴随一个迭代:

public class MyGenCollection : IEnumerable<int>
{
  int[] data = {1, 2, 3};

  public IEnumerator<int> GetEnumerator()
  {
    foreach (int i in data)
      yield return i;
  }

  IEnumerator IEnumerable.GetEnumerator()     // Explicit implementation
  {                                           // keeps it hidden.
    return GetEnumerator();
  }
}

直接实现IEnumerable<T>:

class MyIntList : IEnumerable<int>
{
  int[] data = { 1, 2, 3 };

  // The generic enumerator is compatible with both IEnumerable and
  // IEnumerable<T>. We implement the nongeneric GetEnumerator method
  // explicitly to avoid a naming conflict.

  public IEnumerator<int> GetEnumerator() { return new Enumerator(this); }
  IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(this); }

  class Enumerator : IEnumerator<int>
  {
    int currentIndex = -1;
    MyIntList collection;   

    internal Enumerator (MyIntList collection)
    {
      this.collection = collection;
    }

    public int Current { get { return collection.data [currentIndex]; } }
    object IEnumerator.Current { get { return Current; } }

    public bool MoveNext()
    {
      return ++currentIndex < collection.data.Length;
    }

    public void Reset() { currentIndex = -1; }

    // Given we don’t need a Dispose method, it’s good practice to
    // implement it explicitly, so it’s hidden from the public interface.

    void IDisposable.Dispose() {}
  }
}

使用List<T>:

List<string> words = new List<string>();    // New string-typed list

words.Add ("melon");
words.Add ("avocado");
words.AddRange (new string[] { "banana", "plum" } );
words.Insert (0, "lemon");                                  // insert at
words.InsertRange (0, new string[] { "peach", "nashi" });   // start

words.Remove ("melon");
words.RemoveAt (3);                         // Remove the 4th element
words.RemoveRange (0, 2);                   // Remove first 2 elements

// Remove all strings starting in 'n':
words.RemoveAll (delegate (string s) { return s.StartsWith ("n"); });

Console.WriteLine (words [0]);                          // first word
Console.WriteLine (words [words.Count - 1]);            // last word
foreach (string s in words) Console.WriteLine (s);      // all words
List<string> subset = words.GetRange (1, 2);            // 2nd->3rd words

string[] wordsArray = words.ToArray();    // Creates a new typed array
  
// Copy first two elements to the end of an existing array:
string[] existing = new string [1000];
words.CopyTo (0, existing, 998, 2);

List<string> bigWords = words.ConvertAll <string>        // Converts to
 (delegate (string s) { return s.ToUpper(); } );        // uppercase

List<int> lengths = words.ConvertAll <int>
 (delegate (string s) { return s.Length; } );

使用LinkedList<T>:

LinkedList<string> tune = new LinkedList<string>();
tune.AddFirst ("do");                           // do
tune.AddLast ("so");                            // do - so

tune.AddAfter (tune.First, "re");               // do - re - so
tune.AddAfter (tune.First.Next, "mi");          // do - re - mi - so
tune.AddBefore (tune.Last, "fa");               // do - re - mi - fa - so

tune.RemoveFirst();                             // re - mi - fa - so
tune.RemoveLast();                              // re - mi - fa

LinkedListNode<string> miNode = tune.Find ("mi");
tune.Remove (miNode);                           // re - fa
tune.AddFirst (miNode);                         // mi - re - fa

foreach (string s in tune) Console.WriteLine (s);

使用Queue<T>:

Queue<int> q = new Queue<int>();
q.Enqueue (10);
q.Enqueue (20);
int[] data = q.ToArray();        // Exports to an array
Console.WriteLine (q.Count);      // "2"
Console.WriteLine (q.Peek());     // "10"
Console.WriteLine (q.Dequeue());  // "10"
Console.WriteLine (q.Dequeue());  // "20"
Console.WriteLine (q.Dequeue());  // throws an exception (queue empty)

使用Stack<T>:

Stack<int> s = new Stack<int>();
s.Push (1);                      //            Stack = 1
s.Push (2);                      //            Stack = 1,2
s.Push (3);                      //            Stack = 1,2,3
Console.WriteLine (s.Count);     // Prints 3
Console.WriteLine (s.Peek());    // Prints 3,  Stack = 1,2,3
Console.WriteLine (s.Pop());     // Prints 3,  Stack = 1,2
Console.WriteLine (s.Pop());     // Prints 2,  Stack = 1
Console.WriteLine (s.Pop());     // Prints 1,  Stack = <empty>
Console.WriteLine (s.Pop());     // throws exception

使用HashSet<T>:

HashSet<char> letters = new HashSet<char> ("the quick brown fox");

Console.WriteLine (letters.Contains ('t'));      // true
Console.WriteLine (letters.Contains ('j'));      // false

foreach (char c in letters) Console.Write (c);   // the quickbrownfx
HashSet<char> letters = new HashSet<char> ("the quick brown fox");
letters.IntersectWith ("aeiou");
foreach (char c in letters) Console.Write (c);     // euio
HashSet<char> letters = new HashSet<char> ("the quick brown fox");
letters.ExceptWith ("aeiou");
foreach (char c in letters) Console.Write (c);     // th qckbrwnfx
HashSet<char> letters = new HashSet<char> ("the quick brown fox");
letters.SymmetricExceptWith ("the lazy brown fox");
foreach (char c in letters) Console.Write (c);     // quicklazy

使用Dictionary<TKey,TValue>:

var d = new Dictionary<string, int>();

d.Add("One", 1);
d["Two"] = 2;     // adds to dictionary because "two" not already present
d["Two"] = 22;    // updates dictionary because "two" is now present
d["Three"] = 3;

Console.WriteLine (d["Two"]);                // Prints "22"
Console.WriteLine (d.ContainsKey ("One"));   // true (fast operation)
Console.WriteLine (d.ContainsValue (3));     // true (slow operation)
int val = 0;
if (!d.TryGetValue ("onE", out val))
  Console.WriteLine ("No val");              // "No val" (case sensitive)

// Three different ways to enumerate the dictionary:

foreach (KeyValuePair<string, int> kv in d)          //  One ; 1
  Console.WriteLine (kv.Key + "; " + kv.Value);      //  Two ; 22
                                                     //  Three ; 3

foreach (string s in d.Keys) Console.Write (s);      // OneTwoThree
Console.WriteLine();
foreach (int i in d.Values) Console.Write (i);       // 1223

Using SortedDictionary<TKey,TValue>:

// MethodInfo is in the System.Reflection namespace

var sorted = new SortedList <string, MethodInfo>();

foreach (MethodInfo m in typeof (object).GetMethods())
  sorted [m.Name] = m;

foreach (string name in sorted.Keys)
  Console.WriteLine (name);

foreach (MethodInfo m in sorted.Values) 
  Console.WriteLine (m.Name + " returns a " + m.ReturnType);

Console.WriteLine (sorted ["GetHashCode"]);      // Int32 GetHashCode()

Console.WriteLine (sorted.Keys  [sorted.Count - 1]);            // ToString
Console.WriteLine (sorted.Values[sorted.Count - 1].IsVirtual);  // True

扩展Collection<T>:

public class Animal
{
  public string Name;
  public int Popularity;
  public Zoo Zoo { get; internal set; }

  public Animal(string name, int popularity)
  {
    Name = name; Popularity = popularity;
  }
}

public class AnimalCollection : Collection <Animal>
{
  Zoo zoo;
  public AnimalCollection (Zoo zoo) { this.zoo = zoo; }

  protected override void InsertItem (int index, Animal item)
  {
    base.InsertItem (index, item);
    item.Zoo = zoo;
  }
  protected override void SetItem (int index, Animal item)
  {
    base.SetItem (index, item);
    item.Zoo = zoo;
  }
  protected override void RemoveItem (int index)
  {
    this [index].Zoo = null;
    base.RemoveItem (index);
  }
  protected override void ClearItems()
  {
    foreach (Animal a in this) a.Zoo = null;
    base.ClearItems();
  }
}

public class Zoo
{
  public readonly AnimalCollection Animals;
  public Zoo() { Animals = new AnimalCollection (this); }
}

扩展KeyedCollection<,>:

public class Animal
{
  string name;
  public string Name
  {
    get { return name; }
    set {
      if (Zoo != null) Zoo.NotifyNameChange (this, value);
      name = value;
    }
  }
  public int Popularity;
  public Zoo Zoo { get; internal set; }

  public Animal (string name, int popularity)
  {
    Name = name; Popularity = popularity;
  }
}

public class AnimalCollection : KeyedCollection <string, Animal>
{
  Zoo zoo;
  public AnimalCollection (Zoo zoo) { this.zoo = zoo; }

  internal void NotifyNameChange (Animal a, string newName)
  {
    this.ChangeItemKey (a, newName);
  }

  protected override string GetKeyForItem (Animal item)
  {
    return item.Name;
  }

  // The following methods would be implemented as in the previous example
  protected override void InsertItem (int index, Animal item)...
  protected override void SetItem (int index, Animal item)...
  protected override void RemoveItem (int index)...
  protected override void ClearItems()...
}

public class Zoo
{
  public readonly AnimalCollection Animals;
  public Zoo() { Animals = new AnimalCollection (this); }
}

class Program
{
  static void Main()
  {
    Zoo zoo = new Zoo();
    zoo.Animals.Add (new Animal ("Kangaroo", 10));
    zoo.Animals.Add (new Animal ("Mr Sea Lion", 20));
    Console.WriteLine (zoo.Animals [0].Popularity);               // 10
    Console.WriteLine (zoo.Animals ["Mr Sea Lion"].Popularity);   // 20
    zoo.Animals ["Kangaroo"].Name = "Mr Roo";
    Console.WriteLine (zoo.Animals ["Mr Roo"].Popularity);        // 10
  }
}
使用EqualityComparer:
public class Customer
{
  public string LastName;
  public string FirstName;

  public Customer (string last, string first)
  {
    LastName = last;
    FirstName = first;
  }
}

public class LastFirstEqComparer : EqualityComparer <Customer>
{
  public override bool Equals (Customer x, Customer y)
  {
    return x.LastName == y.LastName && x.FirstName == y.FirstName;
  }

  public override int GetHashCode (Customer obj)
  {
    return (obj.LastName + ";" + obj.FirstName).GetHashCode();
  }
}

static void Main()
{
  Customer c1 = new Customer ("Bloggs", "Joe");
  Customer c2 = new Customer ("Bloggs", "Joe");

  // Because we’ve not overridden object.Equals, normal reference
  // type equality semantics apply:

  Console.WriteLine (c1 == c2);               // false
  Console.WriteLine (c1.Equals (c2));         // false

  Dictionary<Customer, string> d = new Dictionary<Customer, string>();
  d [c1] = "Joe";
  Console.WriteLine (d.ContainsKey (c2));         // false

  // Now with the custom equality comparer:
  
  LastFirstEqComparer eq = new LastFirstEqComparer();
  d = new Dictionary<Customer, string> (eq);
  d [c1] = "Joe";
  Console.WriteLine (d.ContainsKey (c2));         // true
}

使用IComparer接口:

class Wish
{
  public string Name;
  public int Priority;

  public Wish (string name, int priority)
  {
    Name = name;
    Priority = priority;
  }
}

class PriorityComparer : Comparer <Wish>
{
  public override int Compare (Wish x, Wish y)
  {
    if (object.Equals (x, y)) return 0;          // Fail-safe check
    return x.Priority.CompareTo (y.Priority);
  }
}
static void Main()
{
  List<Wish> wishList = new List<Wish>();
  wishList.Add (new Wish ("Peace", 2));
  wishList.Add (new Wish ("Wealth", 3));
  wishList.Add (new Wish ("Love", 2));
  wishList.Add (new Wish ("3 more wishes", 1));

  wishList.Sort (new PriorityComparer());
  foreach (Wish w in wishList) Console.Write (w.Name + " | ");
}

SurnameComparer:

class SurnameComparer : Comparer <string>
{
  StringComparer strCmp;
  
  public SurnameComparer (CultureInfo ci)
  {
    // Create a case-sensitive, culture-sensitive string comparer
    strCmp = StringComparer.Create (ci, false);
  }

  string Normalize (string s)
  {
    s = s.Trim();
    if (s.ToUpper().StartsWith ("MC")) s = "MAC" + s.Substring (2);
    return s;
  }

  public override int Compare (string x, string y)
  {
    // Directly call Compare on our culture-aware StringComparer
    return strCmp.Compare (Normalize (x), Normalize (y));
  }
}
目录
打赏
0
0
0
0
20
分享
相关文章
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
42 11
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
59 10
C#/.NET/.NET Core学习路线集合,学习不迷路!
C#/.NET/.NET Core学习路线集合,学习不迷路!
213 0
C#/.NET/.NET Core开发实战教程集合
C#/.NET/.NET Core开发实战教程集合
并发集合与任务并行库:C#中的高效编程实践
在现代软件开发中,多核处理器普及使多线程编程成为提升性能的关键。然而,传统同步模型在高并发下易引发死锁等问题。为此,.NET Framework引入了任务并行库(TPL)和并发集合,简化并发编程并增强代码可维护性。并发集合允许多线程安全访问,如`ConcurrentQueue&lt;T&gt;`和`ConcurrentDictionary&lt;TKey, TValue&gt;`,有效避免数据不一致。TPL则通过`Task`类实现异步操作,提高开发效率。正确使用这些工具可显著提升程序性能,但也需注意任务取消和异常处理等常见问题。
80 1
|
6月前
|
C# 一分钟浅谈:数组与集合类的基本操作
【9月更文挑战第1天】本文详细介绍了C#中数组和集合类的基本操作,包括创建、访问、遍历及常见问题的解决方法。数组适用于固定长度的数据存储,而集合类如`List<T>`则提供了动态扩展的能力。文章通过示例代码展示了如何处理索引越界、数组长度不可变及集合容量不足等问题,并提供了解决方案。掌握这些基础知识可使程序更加高效和清晰。
115 2
|
7月前
|
C# 集合语法全解
本文详细介绍了C#中的集合语法,涵盖Array、List、Queue、Stack、BitArray、Set、Dictionary以及自定义集合Collection的使用方法。主要内容包括: 1. **Array** 2. **List** 3. **Queue** 4. **Stack** 5. **BitArray** 6. **Set** 7. **Dictionary** 8. **自定义集合Collection** 此外,还简要介绍了字符串比较方法`string.Compare`的使用示例。
50 0
C# 读取二维数组集合输出到Word预设表格
C# 读取二维数组集合输出到Word预设表格
C#使用集合组织相关数据
C#使用集合组织相关数据
|
10月前
|
34.C#:listT泛型集合
34.C#:listT泛型集合
74 1