第十一章 集合、比较和转换
- 集合类(Collection Classes)一般用于处理对象列表,其功能比简单数组要多,功能大多是通过实现System.Collections名称空间中的几口而获得的,因此集合的语法已经标准化了。
- ArrayList集合可以用AddRange()方法一次添加好几个项。这个方法接受带有ICollection接口的任何对象,包括数组(Array)。
(InsertRange()添加到指定位置、IndexOf()获得索引) - 简单数组(Array)是强类型化的,可以直接访问它们所包含的项类型,所以可以直接调用项的方法;
ArrayList集合是System.Object对象的集合,所以必须对所有的项进行数据类型转换。p245 - 索引符(indexer)是一种特殊类型的属性,可以把它添加到一个类中,以提供类似于数组的访问。
- 定义集合:
View Code
1 public class Animals : System.Collections.CollectionBase 2 { 3 public void Add(Animal newAnimal) 4 { 5 List.Add(newAnimal); 6 } 7 public void Remove(Animal oldAnimal) 8 { 9 List.Remove(oldAnimal); 10 } 11 public Animals() 12 { } 13 public Animal this[int animalIndex] 14 { 15 get 16 { 17 return (Animal)List[animalIndex]; 18 } 19 set 20 { 21 List[animalIndex] = value; 22 } 23 } 24 }
View Code1 class AnimalsDic : DictionaryBase 2 { 3 public void Add(string newID, Animal newAnimal) 4 { 5 Dictionary.Add(newID, newAnimal); 6 } 7 public void Remove(string animalID) 8 { 9 Dictionary.Remove(animalID); 10 } 11 public AnimalsDic() { } 12 public Animal this[string animalID] 13 { 14 get { return this[animalID]; } 15 set { this[animalID] = value; } 16 } 17 }
- 迭代器:它是一个代码块,按顺序提供了要在foreach循环中使用的所有值。使用yield关键字选择要在foreach循环中使用的值(yield return value;)。
View Code
1 class Odd 2 { 3 private long min; 4 private long max; 5 6 public Odd() 7 : this(1, 200) 8 { } 9 10 public Odd(long minnum, long maxnum) 11 { 12 this.min = minnum < 1 ? 1 : minnum; 13 this.max = maxnum; 14 } 15 16 public IEnumerator GetEnumerator() 17 { 18 for (long possibleOdd = min; possibleOdd <= max; possibleOdd++) 19 { 20 if (possibleOdd%2!=0) 21 { 22 yield return possibleOdd; 23 } 24 } 25 } 26 }
View Code1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Odd prime = new Odd(1, 1000); 6 foreach (long item in prime) 7 { 8 Console.Write(item+" "); 9 } 10 Console.ReadKey(); 11 } 12 }
View Code1 class AnimalsDic : DictionaryBase 2 { 3 public void Add(string newID, Animal newAnimal) 4 { 5 Dictionary.Add(newID, newAnimal); 6 } 7 public void Remove(string animalID) 8 { 9 Dictionary.Remove(animalID); 10 } 11 public AnimalsDic() { } 12 public Animal this[string animalID] 13 { 14 get { return this[animalID]; } 15 set { this[animalID] = value; } 16 } 17 public new IEnumerator GetEnumerator() 18 { 19 foreach (object animal in Dictionary.Values) 20 { 21 yield return (Animal)animal; 22 } 23 } 24 }
View Code1 class Program 2 { 3 static void Main(string[] args) 4 { 5 AnimalsDic animalDic = new AnimalsDic(); 6 animalDic.Add("1", new Cow("Gen")); 7 animalDic.Add("2", new Chicken("Ken")); 8 foreach (Animal animal in animalDic) 9 { 10 Console.WriteLine(animal.Name); 11 } 12 Console.ReadKey(); 13 } 14 }
- 深复制:(有时这是一个递归的过程)实现ICloneable接口,该接口有一个方法Clone(),不带参数,返回Object。
View Code
1 //浅复制 2 class Program 3 { 4 static void Main(string[] args) 5 { 6 Cloner mySource = new Cloner(5); 7 Cloner myTarget = mySource.GetCopy() as Cloner; 8 Console.WriteLine(myTarget.MyContent.Val.ToString()); 9 mySource.MyContent.Val = 2; 10 Console.WriteLine(myTarget.MyContent.Val.ToString()); 11 Console.ReadKey(); 12 } 13 } 14 class Content 15 { 16 public int Val; 17 } 18 class Cloner 19 { 20 public Content MyContent = new Content(); 21 22 public Cloner(int newVal) 23 { 24 MyContent.Val = newVal; 25 } 26 public object GetCopy() 27 { 28 return MemberwiseClone(); 29 } 30 }
View Code1 //深复制 2 class Program 3 { 4 static void Main(string[] args) 5 { 6 Cloner mySource = new Cloner(5); 7 Cloner myTarget = (Cloner)mySource.Clone(); 8 Console.WriteLine(myTarget.MyContent.Val.ToString()); 9 mySource.MyContent.Val = 2; 10 Console.WriteLine(myTarget.MyContent.Val.ToString()); 11 Console.ReadKey(); 12 } 13 } 14 class Content : ICloneable 15 { 16 public int Val; 17 public object Clone() 18 { 19 Content clonedContent = new Content(); 20 clonedContent.Val = this.Val; 21 return clonedContent; 22 } 23 } 24 class Cloner : ICloneable 25 { 26 public Content MyContent = new Content(); 27 28 public Cloner(int newVal) 29 { 30 MyContent.Val = newVal; 31 } 32 public Cloner() 33 { } 34 public object Clone() 35 { 36 Cloner clonedCloner = new Cloner(); 37 clonedCloner.MyContent = (Content)this.MyContent.Clone(); 38 return clonedCloner; 39 } 40 }
- 类型比较 : is运算符
View Code
1 if (1 is int) 2 { 3 Console.WriteLine("loss for words"); 4 }
- 运算符重载
View Code
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 MyClass class1 = new MyClass(); 6 class1.val = 1; 7 MyClass class2 = new MyClass(); 8 class2.val = 2; 9 MyClass class3 = new MyClass(); 10 class3 = class1 + class2; 11 Console.WriteLine(class3.val.ToString()); 12 Console.ReadKey(); 13 } 14 } 15 16 public class MyClass 17 { 18 public int val; 19 20 public static MyClass operator +(MyClass class1, MyClass class2) 21 { 22 MyClass class3 = new MyClass(); 23 class3.val = class1.val + class2.val; 24 return class3; 25 } 26 }
- 比较:
●IComparable:在要比较的对象的类中实现,可以比较该对象和另一个对象。
●Icomparer:在一个单独的类中实现,可以比较任意两个对象。View Code1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Collections; 6 7 namespace Compare 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 ArrayList list = new ArrayList(); 14 list.Add(new Person("sam", 24)); 15 list.Add(new Person("dean", 26)); 16 list.Add(new Person("cass", 1500)); 17 list.Add(new Person("bob", 53)); 18 19 list.Sort();//Person 默认 Age 排序 20 21 foreach (var item in list) 22 { 23 Person p = item as Person; 24 Console.WriteLine("{0}:{1}", p.Name, p.Age); 25 } 26 27 Console.WriteLine(); 28 29 list.Sort(new PersonCompareByName()); 30 31 foreach (var item in list) 32 { 33 Person p = item as Person; 34 Console.WriteLine("{0}:{1}", p.Name, p.Age); 35 } 36 37 Console.ReadKey(); 38 } 39 } 40 41 public class Person : IComparable 42 { 43 public string Name; 44 public int Age; 45 46 public Person(string name, int age) 47 { 48 this.Name = name; 49 this.Age = age; 50 } 51 52 public int CompareTo(object obj) 53 { 54 if (obj is Person) 55 { 56 return this.Age - ((Person)obj).Age; 57 } 58 else 59 { 60 throw new ArgumentException("xxx"); 61 } 62 } 63 } 64 65 public class PersonCompareByName : IComparer 66 { 67 public int Compare(object obj1, object obj2) 68 { 69 if (obj1 is Person && obj2 is Person) 70 { 71 return Comparer.Default.Compare(((Person)obj1).Name, ((Person)obj2).Name); 72 } 73 else 74 { 75 throw new ArgumentException("xxx"); 76 } 77 } 78 } 79 }
- 转换:重载转换运算符,在不相关的类型之间转换。
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Convert 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 MyClass1 myClass1 = new MyClass1(10); 13 MyClass2 myClass2 = myClass1; 14 15 Console.WriteLine(myClass2.val.ToString()); 16 17 //MyClass2 myClass2_2 = new MyClass2(10000000000); 18 MyClass2 myClass2_2 = new MyClass2(10000); 19 MyClass1 myClass1_2 = new MyClass1(); 20 21 try 22 { 23 myClass1_2 = (MyClass1)myClass2_2; 24 } 25 catch (Exception ex) 26 { 27 Console.WriteLine(ex.Message); 28 } 29 30 Console.WriteLine(myClass1_2.val.ToString()); 31 32 Console.ReadKey(); 33 } 34 } 35 36 public class MyClass1 37 { 38 public int val; 39 40 public MyClass1() 41 { } 42 43 public MyClass1(int val) 44 { 45 this.val = val; 46 } 47 48 public static implicit operator MyClass2(MyClass1 myClass1) 49 { 50 MyClass2 myClass2 = new MyClass2(); 51 myClass2.val = myClass1.val; 52 return myClass2; 53 } 54 } 55 public class MyClass2 56 { 57 public double val; 58 59 public MyClass2() 60 { } 61 62 public MyClass2(double val) 63 { 64 this.val = val; 65 } 66 67 public static explicit operator MyClass1(MyClass2 myClass2) 68 { 69 MyClass1 myClass1 = new MyClass1(); 70 myClass1.val = System.Convert.ToInt32(myClass2.val); 71 return myClass1; 72 } 73 } 74 75 76 }
- as运算符:<operand> as <type>,要注意的是,如果不能从<operand>转换为<type>,则表达式的结果就是null,而不会抛异常。