实现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)); } }