您的位置:首页 > 编程语言 > C#

《C#高级教程》学习笔记7

2014-12-12 00:08 363 查看
第七,八,九,十天

(最近几天因为课程设计原因耽误了C#学习进程,刚花了大量精力干掉课程设计,然后又花了挺多时间玩游戏看漫画来恢复精力,正当准备努力学习的时候,同学却来找我一起挑战做手机游戏来参加比赛,然后关于游戏类型与主题讨论了很长时间,于是学习便呵呵掉了,之后还要花时间去研究安卓,真是作死的节奏了)

CreateInstance()方法还有很多重载版本,可创建多维数组及不基于0的数组

int[] length={2,3};

int[] lowerBounds={1,10};

Array racers=Array.CreateInstance(typeof(Person),length,lowerBounds);

racers.SetValue(new Person{

FirstName="A";

SecondName="B";

},1,10);

6.5.2复制数组

数组是引用类型,直接赋值只是两个引用而且。

复制数组,会使数组实现ICloneable接口。这个接口定义的Clone()方法会创建数组的浅表副本。

int[] intArray1={1,2};

int[] intArray2=(int[])intArray1.Clone();

数组里有引用无素,则只复制引用,不复制元素

还可以使用Array.Copy()方法创建浅表副本。与Clone()方法的区别:Clone()会创建一个新数组,Copy()方法必须传递阶数相同用有足够元素的已有数组。

6.5.3排序

Array类使用QuickSort算法对数组中的元素进行排序。

Sort()方法需要数组中的元素实现IComparable接口。

对数组使用自定义类,则该类必须实现IComparable接口,此接口里只定义了一个方法CompareTo(),方法返回0。该实例对象应排在参数对象的前面则返回小于0的值,

相反则大于0

不能修改在数组中用作元素的类,就可以实现IComparer接口或IComparer<T>接口。这两个接口定义了方法Compare()。

IComparer接口独立于要比较的类。

Array.sort()时,第一个参为数组,第二个为new的比较器

6.6数组作为参数

public void A(Person[] person){}

public Person[] B(){}

6.6.1数组协变

数组支持协变,这表示数组可以声明为基类,其派生类型的元素可以赋予数组元素。

static void DisplayArray(object[] data){}

6.6.2 ArraySegment<T>

结构ArraySegment<T>表示数组的一段。把数组部分复制到方法去。

传参时:

(ArraySegment<int>[] segments)

之类

用例:

int[] ar1={1,4,5,11,13,18};

int[] ar2={3,4,5,18,21,27,33};

var segments = new ArraySegment<int>(2){

new ArraySegment<int>(ar1,0,3),

new ArraySegment<int>(ar2,3,3)

}

6.7枚举

foreach,可以迭代集合中的元素,且无需知道集合中的元素个数。

数组或集合实现带GetEnumerator()方法的IEnumerable接口。

GetEnumerator()方法返回一个实现IEnumerable接口的枚举。

接着,foreach语句就可以使用IEnumerable接口迭代集合。

6.7.1 IEnumerator接口

foreach语句作用IEnumerator接口的方法和属性,迭代集合中的所有元素。

为此IEnumerator定义了Current属性来返回光标所在的元素,

该接口的MoveNext()方法,移动到集合的下一个元素上,如果有这个元素就返加true,否则false。

IEnumerator<T>派生自接口IDisposable,因此定义了Dispose()方法来清理枚学会举器占用的资源。

6.7.2 foreach语句

C#的foreach语句不会解析为IL代码中的foreach语句。

foreach(var p in persons){

Console.WriteLine(p);

}

解析:

IEnumerator<Person> enumerator=persons.GetEnumerator();

while(enumerator.MoveNext()){

Person p=enumerator.Current();

Console.WriteLine(p);

}

6.7.3 yield语句

yield语句返回集合的一个元素,并移动到下一个元素,yield break可停止迭代。

例:

using System;

using System.Collections;

namespace Wrox.ProCShape.Arrays{

public class HelloCollection{

public IEnumerator<String> GetEnumerator(){

yield return "Hello";

yield return "World";

}

}

}

然后用foreach迭代语句

使用迭代块,编译器会生成一个yield类型,其中包含一个状态机,如下面的代码段所示。

public class HelloCollection{

public IEnumerator GetEnumerator(){

return new Enumerator(0);

}

}

public class Enumerator:IEnumerator<string>,IEnumerator,IDisposable{

private int state;

private string current;

public Enumerator(int state){

this.state=state;

}

bool System.Collections.IEnumerator.MoveNext(){

switch(state){

case 0:

current="Hello";

state=1;

return true;

case 1:

current="World";

state=2;

return true;

}

return false;

}

void System.Collections.IEnumerator.Reset(){

throw new NotSupportedException();

}

string System.Collections.Generic.IEnumerator<string>.Current{

get{

return current;

}

}

object System.Collections.IEnumerator.Current{

get{

return current;

}

}

void IDisposable.Dispose(){}

}

1.迭代集合的不同方式

例:

public class MusicTitles{

string[] names={"A","B","C","D"};

public IEnumerator<string> GetEnumerator(){

for(int i=0;i<4;i++){

yeild return name[i];

}

}

public IEnumerable<string> Reverse(){

for(int i=3;i>=0;i--){

yeild return name[i];

}

}

public IEnumerable<string> Subset(int index,int length){

for(int i=index;i<index+length;i++){

yield return name[i];

}

}

}

用:

var titles=new MusicTitles();

foreach(var title in titles){

Console.WriteLine(title);

}

Console.WriteLine("reverse");

foreach(var title in titles.Reverse()){

Console.WriteLine(title);

}

Console.WriteLine("subset");

foreach(var title in titles.Subset(2,2)){

Console.WriteLine(title);

}

2.用yield return返回枚举器

public class GameMove{

private IEnumerator cross;

private IEnumerator circle;

private GameMove{

cross=Cross();

circle=Circle();

}

private int move=0;

private int MaxMoves=0;

public IEnumerator Cross(){

while(true){

Console.WriteLine("Cross,move{0}",move);

if(++move>=MaxMoves)

yield break;

yield return circle;

}

}

public IEnumerator Circle(){

while(true){

Console.WriteLine("Circle,move{0}",move);

if(++move>=MaxMoves)

yield break;

yield return cross;

}

}

}

var game=new GameMove();

IEnumerator enumerator=game.Cross();

while(enumerator.MoveNext()){

enumerator=enumerator.Current as IEnumerator;

}

输出:

Cross,move 0

Cicle,move 1

Cross,move 2

Cicle,move 3

Cross,move 4

Cicle,move 5

Cross,move 6

Cicle,move 7

Cross,move 8

6.8元组

数组合并了相同类型的对象,而元组合并了不同类型的对象。

在.NET Framework中,元组可用于所有的.NET语言。

.NET Framework定义了8个泛型Tuple类(自.NET4.0以来)和一个静态Tuple类。

不同泛型Tuple类支持不同数量的元素。如Tuple<T1>包含一个元素,Tuple<T1,T2>包含两个元素,以此类推。

例:

public static Tuple<int,int> Divide(int dividend,int divisor){

int result=dividend/divisor;

int reminder=dividend%divisor;

return Tuple.Create<int,int>(result,reminder);

}

调用:

var result=Divide(5,2);

Console.WriteLine("{0},{1}",result.Item1,result.Item2);

如果元组包含的项超过8个,就可以使用带8个参数的Tuple类定义。最后一个传元组。

public class Tuple<T1,T2,T3,T4,T5,T6,T7,TRest>

(2014.12.12 158页,还有1517-158=1359)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: