1、用 GetEnumerator() 遍历dictionary 和 list ,避免使用 foreach
2、dictionary 使用 TryGetValue 一次判断取值,避免两次访问
3、值类型使用引用方式传递,可提高效率 ref
4、避免无意义的初始化,C# 默认初始化是清除内存,所以无意的初始化,会增加内存
5、字符串判断, 使用 比较length ==0 效率更高
6、cahe 数据,可以避免反复访问;
7、减少字符串的拼接,每次拼接都会产生新的字符串,产生CG
8、常量使用const 或 readonly 修饰
9、用using 包裹,可自动调用Dispose
using System; using System.Collections.Generic; using System.Text; namespace CustomGenericCollection { #region 汽车的定义 public class Car { public string PetName; public int Speed; public Car(string name, int currentSpeed) { PetName = name; Speed = currentSpeed; } public Car() { } } public class SportsCar : Car { public SportsCar(string p, int s) : base(p, s) { } // 其他方法 } public class MiniVan : Car { public MiniVan(string p, int s) : base(p, s) { } // 其他方法 } #endregion #region 自定义泛型集合 public class CarCollection<T> : IEnumerable<T> where T : Car//:下面的泛型集合类的项目必须是Car 或Car的继承类 { private List<T> arCars = new List<T>(); public T GetCar(int pos) { return arCars[pos]; } public void AddCar(T c) { arCars.Add(c); } public void ClearCars() { arCars.Clear(); } public int Count { get { return arCars.Count; } } // IEnumerable<T>扩展自IEnumerable的,因此,我们需要实现的GetEnumerator()方法的两个版本。 System.Collections.Generic.IEnumerator<T> IEnumerable<T>.GetEnumerator() { return arCars.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return arCars.GetEnumerator(); } public void PrintPetName(int pos) { Console.WriteLine(arCars[pos].PetName); } } #endregion class Program { static void Main(string[] args) { Console.WriteLine("***** Custom Generic Collection ***** "); CarCollection<Car> myCars = new CarCollection<Car>(); myCars.AddCar(new Car("Rusty", 20)); myCars.AddCar(new Car("Zippy", 90)); foreach (Car c in myCars) { Console.WriteLine("PetName: {0}, Speed: {1}", c.PetName, c.Speed); } Console.WriteLine(); // CarCollection<Car> can hold any type deriving from Car. CarCollection<Car> myAutos = new CarCollection<Car>(); myAutos.AddCar(new MiniVan("Family Truckster", 55)); myAutos.AddCar(new SportsCar("Crusher", 40)); foreach (Car c in myAutos) { Console.WriteLine("Type: {0}, PetName: {1}, Speed: {2}", c.GetType().Name, c.PetName, c.Speed); } Console.ReadLine(); } } }
微软官方:
using System; using System.Collections; // Simple business object. public class Person { public Person(string fName, string lName) { this.firstName = fName; this.lastName = lName; } public string firstName; public string lastName; } // Collection of Person objects. This class // implements IEnumerable so that it can be used // with ForEach syntax. public class People : IEnumerable { private Person[] _people; public People(Person[] pArray) { _people = new Person[pArray.Length]; for (int i = 0; i < pArray.Length; i++) { _people[i] = pArray[i]; } } // Implementation for the GetEnumerator method. IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); } public PeopleEnum GetEnumerator() { return new PeopleEnum(_people); } } // When you implement IEnumerable, you must also implement IEnumerator. public class PeopleEnum : IEnumerator { public Person[] _people; // Enumerators are positioned before the first element // until the first MoveNext() call. int position = -1; public PeopleEnum(Person[] list) { _people = list; } public bool MoveNext() { position++; return (position < _people.Length); } public void Reset() { position = -1; } object IEnumerator.Current { get { return Current; } } public Person Current { get { try { return _people[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } class App { static void Main() { Person[] peopleArray = new Person[3] { new Person("John", "Smith"), new Person("Jim", "Johnson"), new Person("Sue", "Rabon"), }; People peopleList = new People(peopleArray); foreach (Person p in peopleList) Console.WriteLine(p.firstName + " " + p.lastName); Console.Read(); } } /* This code produces output similar to the following: * * John Smith * Jim Johnson * Sue Rabon * */
C# 语言的 foreach
语句(在 Visual Basic 中为 For Each
)隐藏了枚举数的复杂性。 因此,建议使用 foreach
,而不是直接操作枚举数。
枚举器可用于读取集合中的数据,但不能用于修改基础集合。
最初,枚举数定位在集合中第一个元素的前面。 Reset方法还将枚举器恢复到此位置。 在此位置, Current 属性未定义。 因此,在读取的值之前,必须调用 MoveNext 方法,以将枚举器前进到集合的第一个元素 Current 。
在调用 Current 或 MoveNext 之前,Reset 返回同一对象。 MoveNext 将 Current 设置为下一个元素。
如果 MoveNext 越过集合的末尾,则枚举器将定位在集合中最后一个元素之后,并 MoveNext 返回 false
。 当枚举器位于此位置时,对的后续调用 MoveNext 也将返回 false
。 如果最后一次调用 MoveNext 返回 false
, Current 则未定义。 若要再次将 Current 设置为集合的第一个元素,可以调用 Reset 并接着调用 MoveNext。
如果对集合所做的更改(如添加、修改或删除元素),则枚举器的行为是不确定的。
枚举数没有对集合的独占访问权;因此,从头到尾对一个集合进行枚举在本质上不是一个线程安全的过程。 若要确保枚举过程中的线程安全性,可以在整个枚举过程中锁定集合。 若要允许多个线程访问集合以进行读写操作,则必须实现自己的同步。