C# 迭代器与迭代器块的使用

迭代器模式是行为模式的一种,他能够有效地构建数据管道,迭代器相当于数据库当中的游标,它只能够向前移动,并且在一个数据序列当中可能会存在多个迭代器。在C#1当中你要实现一个迭代器的话,得编写相当多的代码。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 public class IterationSample : IEnumerable { object[] values; int startingPoint; public IterationSample(object[] values,int startingPoint) { this.

C# 泛型静态字段与静态构造函数

每个封闭类型都会有一个自己的静态字段集 每个封闭类型的静态构造函数仅会执行一次。 例如: 1 2 3 4 5 6 7 8 9 10 11 public class Outer<T> { public class Inner<U,V> { static Inner() { Console.WriteLine($"Outer<{typeof(T).Name}>,Inner<{typeof(U).Name},{typeof(V).Name}>"); } public void Test(){} } } 那么我们进行以下调用: 1 2 3 Out<int>.Inner<string,DateTime>.Test(); Out<string>.Inner<int,object>.Test(); Out<int>.Innter<string,DateTime>.Test(); 那么第一二行会打印出他们类型参数的Name属性,而第三行由于**每个封闭类型的静态构造函数仅会执行一次。**的规定,所以不会产生任何输出。

C# 中级泛型-泛型比较与类型推断

泛型方法类型推断 有以下代码: 1 2 3 4 5 6 static List<T> MakeList<T>(T first,T second); { ...... } List<string> list = MakeList<string>("a1","b1"); 可以简写成: 1 List<string> list = MakeList("a1","b1"); 在这里就使用到了泛型类型推断,但是类型推断只适用于泛型方法。 默认值表达式 在一个泛型类当中,你如果要知道该类型参数的默认值,不能使用null,因为类型参数可能被约束为值类型,你也不能使用0,因为也有可能被约束为引用类型。在C#2当中提供了默认值表达式default(T),就可以返回类型实参的默认值。 1 2 3 4 5 6 7 8 9 10 static int CompareToDefault<T>(T value) where T : IComparable<T> { return value.CompareTo(default(T)); } Console.WriteLine(ComparaToDefault("x")); //1 Console.WriteLine(ComparaToDefault(10)); //1 Console.WriteLine(ComparaToDefault(0)); //0 Console.WriteLine(ComparaToDefault(-10)); //-1 Console.WriteLine(ComparaToDefault(DateTime.MinValue)); //0 由CompareTo文档指出,所有引用类型的值都大于null,所以返回1,CompareTo,如果比较的值比自己大则为1,相等则为0,小于则为-1。 不过如果传入的是null,以上代码会如预期的抛出NullReferenceException异常,我们可以使用IComparer<T>。 泛型比较 如果一个类型参数是未被约束的,那么只能在泛型类直线中对该类型的值与null进行比较的时候才可以使用!=、==操作符。 如果类型参数被约束为值类型,那么就完全不能使用!=、==操作符。 如果他只是一个引用类型,则只能进行简单的引用比较,可以使用!=、==操作符。 如果他被进一步约束成继承自某个重载了的!=、==操作符的特定类型(即转换类型约束),就会使用重载操作符。 如果调用者指定的类型实参恰巧也进行了重载,那么这个重载操作符是不会使用的 1 2 3 4 5 6 7 8 9 10 static bool AreReferenceEqual<T>(T first,T second) where T : class { return first == second; } string name = "Jon"; string intro1 = "Hello " + name; string intro1 = "Hello " + name; Console.

比较 ArrayList 与 List Of T 之间性能究竟有多大的差别

闲的蛋疼,每天一搏,测试了一下两个集合容器之间性能的差异: ArrayList是一个弱类型的集合列表,每次对其进行操作的时候,不论是存储还是读取,我们都需要经过一次强制类型转换(“装箱/拆箱”)操作才能够正常使用,一两次没有什么问题,但到达一个数量级之后,速度成指数级别变化。 还好在C#2之后引入了强类型集合List,免除了大量数据的集合进行操作的时候性能问题。 测试代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ArrayList _oldList = new ArrayList(); List<int> _newList = new List<int>(); Stopwatch _timerOld = new Stopwatch(); Stopwatch _timerNew = new Stopwatch(); _timerOld.Start(); for(int i = 0;i<9999999;i++) { _oldList.Add(i); } for(int j = 0;j<_oldList.Count;j++) { _oldList[j] = (int)_oldList[j] + 1; } _timerOld.

C# 泛型类型约束

C#泛型是使用的最为广泛的一个特性,在基础框架中四处可见它的身影,泛型将大量C#1当中的安全检查由运行时转换为了编译时执行,在C#1当中,容器ArrayList则是一个代表,他并不是类型安全的,每次从中读取数据,都需要进行一次强制类型转换或者装箱/拆箱操作,引发的性能问题与代码问题数不胜数。 在C#2当中,泛型的引入解决了这一问题,它将类型参数化,如同函数参数一样,类型参数从属于类型,而非从属于某个特定的构造函数。 在C#当中,例如已经提供了类型实参的泛型类型则是已构造类型,没有提供的则为未绑定泛型类型。 在其中,泛型定义的时候为我们提供了多种泛型约束方法,有以下四种: 引用类型约束。 值类型约束。 构造函数类型约束。 转换类型约束。 引用类型约束,如下: 1 struct RefSample<T> where T : class 有效的封闭类型: 1 2 3 RefSample<IDisposable>; RefSample<string>; RefSample<int[]>; 无效的封闭类型: 1 2 RefSample<int>; RefSample<Guid>; 当这样约束了一个类型参数的时候,可以对类型参数进行==,!=来比较引用。 值类型约束 1 class ValSample<T> where T : struct 有效的封闭类型: 1 2 ValSample<int>; ValSample<FileMode>; // 可为枚举 无效的封闭类型: 1 ValSample<object>; 当类型参数约束为值类型的时候,无法通过!=,==来进行比较。 构造函数约束 1 2 3 4 public T CreateInstance<T> where T : new() { return new T(); } 本约束必须是所有类型参数的最后一个约束,它将会检查类型实参是否有一个可用于创建类型实例的无参构造函数。 例如以下调用,是有效的: 1 int a = CreateInstance<int>(); 但是string是没有无参构造函数的,所以以下调用无效:
Built with Hugo
主题 StackJimmy 设计