Chapter6 方法 Var关键字 Var关键字并不是表示特殊变量。它只是句法上的速记,表示任何可以从初始化语句的右边推断出的类型。 使用Var关键字有一些重要的条件:
只能用于局部变量,不能用于字段;
只能在变量声明中包含初始化时使用;
一旦编辑器推断出变量的类型,它就是固定且不能更改的。局部函数 从C#7.0开始,可以在一个方法中声明另一个单独的方法。这样可以将嵌入的方法跟其他的代码隔离开来,所以它只能在包含它的方法内调用。 与局部变量必须在使用之前进行声明不同,你可以在包含方法的任意位置声明局部函数。1 2 3 4 5 6 7 8 9 10 11 public int TestLocalFunc (int index ) { int LocalFunc (int index ) { return index * index; } i int results = LocalFunc(index); return results; }
or1 2 3 4 5 6 7 8 9 10 11 public int TestLocalFunc (int index ){ int results = LocalFunc(index); int LocalFunc (int index ) { return index * index; } return results; }
ref局部变量
你可以使用这个功能创建一个变量的别名,即使引用的对象是值类型。
对任意一个变量的赋值都会反映到另一个变量上,因为他们引用的是相同的对象,即使是值类型。1 2 3 4 5 6 7 8 9 10 11 12 int x = 1 ; ref int y = ref x; Console.WriteLine($"x={x} ,y={y} " ); x = 666 ; Console.WriteLine($"x={x} ,y={y} " ); y = 888 ; Console.WriteLine($"x={x} ,y={y} " ); --------------------------------------------------------------------------------------------------------------------------------------------- x=1 ,y=1 x=666 ,y=666 x=888 ,y=888
ref返回 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 class Test { private int Score = 5 ; public ref int RefToValue ( ) { return ref Score; } public void Display ( ) { Console.WriteLine($"Value inside class object:{Score} " ); } } --------------------------------------------------------------------------------------------------------------------------------------------- static void Main (string [] args ) { Test test = new Test(); test.Display(); ref int VOutSide = ref test.RefToValue(); VOutSide = 10 ; test.Display(); Console.ReadKey(); } --------------------------------------------------------------------------------------------------------------------------------------------- Value inside class object :5 Value inside class object :10
递归图解 Chapter7 深入理解类 静态构造函数 实例构造函数初始化类的每个新实例,而static构造函数初始化类级别的项。通常,静态构造函数初始化类的静态字段。 不能从程序中显式调用静态构造函数,系统会自动调用他们。
在类的任何实例被创建之前。
在类的任何静态成员被引用之前。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 class Test { public Test ( ) { Console.WriteLine("Normal Construct" ); } public static int index = 1 ; static Test ( ) { Console.WriteLine("Static Construct" ); index = 10 ; } } --------------------------------------------------------------------------------------------------------------------------------------------- static void Main (string [] args ) { Console.WriteLine(Test.index); Console.ReadKey(); } --------------------------------------------------------------------------------------------------------------------------------------------- Static Construct 10
对象初始化语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Test { public int x = 1 ; public int y = 2 ; public Test (int x,int y ) { x = 3 ; y = 4 ; Console.WriteLine("Construct Finish" ); } } --------------------------------------------------------------------------------------------------------------------------------------------- static void Main (string [] args ) { Test test = new Test(7 ,8 ){x =5 ,y=6 }; Console.WriteLine($"Test x={test.x} y={test.y} " ); Console.ReadKey(); } --------------------------------------------------------------------------------------------------------------------------------------------- Construct Finish Test x=5 y=6
索引器 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 class Test { private string oneStr; private string twoStr; private string threeStr; public string this [int index] { set { switch (index) { case 1 : oneStr = value ; break ; case 2 : twoStr = value ; break ; case 3 : threeStr = value ; break ; } } get { switch (index) { case 1 : return oneStr; case 2 : return twoStr; case 3 : return threeStr; default : return "" ; } } } } --------------------------------------------------------------------------------------------------------------------------------------------- static void Main (string [] args ) { Test test = new Test(); test[1 ] = "oneStroneStr" ; test[2 ] = "twoStrtwoStr" ; test[3 ] = "threeStrthreeStr" ; Console.WriteLine($"1={test[1 ]} 2={test[2 ]} 3={test[3 ]} " ); Console.ReadKey(); } --------------------------------------------------------------------------------------------------------------------------------------------- 1 =oneStroneStr 2 =twoStrtwoStr 3 =threeStrthreeStr
Chapter8 使用基类的引用 虚方法和覆写方法 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 class BaseTest { public virtual void Print ( ) { Console.WriteLine("IM BaseTest" ); } } class MyTest : BaseTest { public override void Print ( ) { Console.WriteLine("IM MyTest" ); } } --------------------------------------------------------------------------------------------------------------------------------------------- static void Main (string [] args ) { MyTest myTest = new MyTest(); myTest.Print(); BaseTest baseTest = new BaseTest(); baseTest.Print(); BaseTest Back2Base = (BaseTest)myTest; Back2Base.Print(); Console.ReadKey(); } --------------------------------------------------------------------------------------------------------------------------------------------- IM MyTest IM BaseTest IM MyTest
Chapter10 语句 C#托管对象和非托管对象 托管对象指的是.net可以自动进行回收的资源,主要是指托管对象在堆上分配的内存资源。托管资源的回收工作是不需要人工干预的,有.net运行库在合适的时间进行回收。(手动回收GC.Collect)
非托管对象指.net不知道如何回收的资源,最常见的一类非托管资源是包装操作系统资源的对象,例如文件、窗口、网络连接、数据库连接、画刷、图标等。这类资源,垃圾回收器在清理的时候会调用Object.Finalize()方法。默认情况下,方法是空的,对于非托管对象在此方法中需要编写回收非托管对象的代码,以便垃圾回收器正确回收。(例如我们通常打开文件、图片等后需要进行Close()或者Dispose()去释放)。
本来如果按照上面做法,非托管资源也能够由垃圾回收器进行回收,但是非托管资源一般是有限的,比较宝贵的,而垃圾回收器是由CRL自动调用的,这样就无法保证及时的释放掉非托管资源,因此定义了一个Dispose()方法,让使用者能够手动的释放非托管资源。Dispose()方法释放类的托管资源和非托管资源,使用者手动调用此方法后,垃圾回收器不会对此类实例再次进行回收。Dispose()方法是由使用者调用的,在调用时,类的托管资源和非托管资源肯定都未被回收,所以可以同时回收两种资源。
Microsoft为非托管资源的回收专门定义了一个接口:IDisposable,接口中只包含一个Dispose()方法。任何包含非托管资源的类,都应该继承此接口。
在一个包含非托管资源的类中,关于资源释放的标准做法是: (1)继承IDisposable()接口; (2)实现Dispose()方法,在其中释放托管资源和非托管资源,并将对象本身从垃圾回收器中移除(垃圾回收器不在回收此资源); (3)实现类析构函数,在其中释放非托管资源。 这样做的目的是为了更好的提高程序性能,避免内存泄漏,小数据量往往体现不出来,当数据量庞大时就会出现内存不足以及System.OutOfMemoryException:“Exception_WasThrown”的错误。
Chapter13 数组 int[] 一维数组 int[,] 二维数组 int[][] 交错数组
Chapter15 事件 事件访问器 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 56 57 public class TestEvent { public delegate void CustomEvent ( ) ; private CustomEvent myEventHandler; public event CustomEvent MyEventHandler { add { if (value != null ) { myEventHandler += value ; myEventHandler += value ; myEventHandler += value ; } } remove { if (value != null ) { myEventHandler -= value ; myEventHandler -= value ; } } } public void FireAEvent ( ) { if (myEventHandler != null ) { myEventHandler(); } } } --------------------------------------------------------------------------------------------------------------------------------------------- class Program { static void Main (string [] args ) { TestEvent testEvent = new TestEvent(); testEvent.FireAEvent(); testEvent.MyEventHandler += Print; testEvent.MyEventHandler -= Print; testEvent.FireAEvent(); Console.ReadKey(); } static void Print ( ) { Console.WriteLine("Invoke Print" ); } } --------------------------------------------------------------------------------------------------------------------------------------------- Invoke Print
Chapter19 枚举器和迭代器 IEnumerator 枚举器 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 class ColorEnumerator : IEnumerator { string [] colors; int position = -1 ; public ColorEnumerator (string [] theColors ) { colors = new string [theColors.Length]; for (int i = 0 ; i < theColors.Length; i++) { colors[i] = theColors[i]; } } public object Current { get { if (position == -1 || position >= colors.Length) { throw new InvalidOperationException(); } return colors[position]; } } public bool MoveNext ( ) { if (position < colors.Length - 1 ) { position++; return true ; } else { return false ; } } public void Reset ( ) { position = -1 ; } }
IEnumerable 可枚举类型 1 2 3 4 5 6 7 8 9 class Spectrum : IEnumerable { string [] Colors = {"violet" ,"blue" ,"cyan" ,"green" ,"yellow" ,"orange" ,"red" }; public IEnumerator GetEnumerator ( ) { return new ColorEnumerator(Colors); } }
Chapter20 LINQ 查询语法 方法语法 1 2 3 4 5 6 7 8 9 10 11 12 int [] numbers = { 2 , 5 , 28 , 31 , 17 , 16 , 42 };var numsQuery = from n in numbers where n < 20 select n; var numsMethod = numbers.Where(N => N < 20 );int numsCount = (from n in numbers where n < 20 select n).Count();
Chapter21 异步编程 同步编程与异步编程示例 同步编程
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 class MyDownloadString { Stopwatch sw = new Stopwatch(); public void DoRun ( ) { const int LargeNumber = 6 _000_000; sw.Start(); int t1 = CountCharacters(1 , "http://www.microsoft.com" ); int t2 = CountCharacters(2 , "http://www.illustratedcsharp.com" ); CountToALargeNumber(1 , LargeNumber); CountToALargeNumber(2 , LargeNumber); } private int CountCharacters (int id,string urlString ) { WebClient wc1 = new WebClient(); Console.WriteLine("Starting Call {0} : {1}ms" , id, sw.Elapsed.TotalMilliseconds); string result = wc1.DownloadString(new Uri(urlString)); Console.WriteLine("Call {0} completed : {1}ms" , id, sw.Elapsed.TotalMilliseconds); Console.WriteLine("result length ==> {0}" , result.Length); return result.Length; } private void CountToALargeNumber (int id,int value ) { for (long i = 0 ; i < value ; i++) ; Console.WriteLine("End counting {0} : {1}ms" , id, sw.Elapsed.TotalMilliseconds); } } --------------------------------------------------------------------------------------------------------------------------------------------- class Program { static void Main (string [] args ) { MyDownloadString ds = new MyDownloadString(); ds.DoRun(); } } --------------------------------------------------------------------------------------------------------------------------------------------- Starting Call 1 : 20.9274 ms Call 1 completed : 3625.7335 ms result length ==> 180832 Starting Call 2 : 3626.6481 ms Call 2 completed : 4128.4041 ms result length ==> 5164 End counting 1 : 4153.6904 ms End counting 2 : 4177.9644 ms
异步编程
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 class Program { static void Main (string [] args ) { MyDownloadString ds = new MyDownloadString(); ds.DoRun(); } } --------------------------------------------------------------------------------------------------------------------------------------------- class MyDownloadString { Stopwatch sw = new Stopwatch(); public void DoRun ( ) { const int LargeNumber = 6 _000_000; sw.Start(); Task<int > t1 = CountCharactersAsync(1 , "http://www.microsoft.com" ); Task<int > t2 = CountCharactersAsync(2 , "http://www.illustratedcsharp.com" ); CountToALargeNumber(1 , LargeNumber); CountToALargeNumber(2 , LargeNumber); Console.WriteLine("Chars in http://www.microsoft.com: {0}" ,t1.Result); Console.WriteLine("Chars in http://www.illustratedcsharp.com: {0}" , t2.Result); } private async Task<int > CountCharactersAsync (int id,string urlString ) { WebClient wc1 = new WebClient(); Console.WriteLine("Starting Call {0} : {1}ms" , id, sw.Elapsed.TotalMilliseconds); string result = await wc1.DownloadStringTaskAsync(new Uri(urlString)); Console.WriteLine("Call {0} completed : {1}ms" , id, sw.Elapsed.TotalMilliseconds); return result.Length; } private void CountToALargeNumber (int id,int value ) { for (long i = 0 ; i < value ; i++) ; Console.WriteLine("End counting {0} : {1}ms" , id, sw.Elapsed.TotalMilliseconds); } } --------------------------------------------------------------------------------------------------------------------------------------------- Starting Call 1 : 74.7954 ms Starting Call 2 : 771.2391 ms End counting 1 : 791.301 ms End counting 2 : 804.6226 ms Call 1 completed : 1250.2072 ms Chars in http: Call 2 completed : 1615.1967 ms Chars in http: