第19章 泛型
1.泛型概念
泛型提供了一种更准确地使用有一种以上的类型的代码的方式.
泛型允许我们声明类型参数化的代码,我们可以用不同的类型进行实例化.
泛型不是类型,而是类型的模板.
 
2.声明泛型
●在类名之后放置一组尖括号
●在尖括号中用逗号分隔的占位符字符串来表示希望提供的类型,这被叫做类型参数
●在泛型类声明的主体中使用类型参数来表示应该被替代的类型.
eg:声明与实例化
namespace ConsolePractice
{
    class SomeClass<T1, T2>//声明一个泛型,类型参数T1,T2,也不一定要用T,可以用任意字符.
    {
    }
 
    class Class2
    {
        static void Main()
        {
            var first = new SomeClass<short, int>();//构造的类型实例化
            var second = new SomeClass<int, long>();//构造的类型实例化
        }
    }
}
 
3.类型参数的约束
约束使用where子句列出
●每一个有约束的类型参数有自己的where子句
●如果形参有多个约束,它们在where子句中使用逗号分隔.
●where子句在类型参数列表的关闭尖括号之后列出
●where子句不使用逗号或其他符号分隔;
●where子句可以以任何次序列出.
●where是上下文关键字,所以可以在其他上下文中使用.
 
4.约束类型与次序
书上没实例,不太懂,详情百度
 
5.泛型方法
eg:声明和调用实例
namespace ConsolePractice
{
    class Simple
    {
        static public void ReverseAndPrint<T>(T[] arr)//声明一个泛型方法,作用:数组倒序
        {
            Array.Reverse(arr);
            foreach (T item in arr)
            {
                Console.Write("{0},", item.ToString());
            }
            Console.WriteLine();
        }
    }
 
    class Program
    {
        static void Main()
        {
            var intArray = new int[] { 3, 5, 7, 9, 11 };//var也可写成int[]
            var stringArray = new string[] { "first", "second", "third" };
            var doubleArray = new double[] { 3.567, 7.891, 2.345 };
 
 
            Simple.ReverseAndPrint<int>(intArray);//调用方法
            Simple.ReverseAndPrint(intArray);//由于编译器可以从方法参数中推断类型参数,我们可以省略类型参数和调用中的尖括号
 
 
            Simple.ReverseAndPrint<string>(stringArray);
            Simple.ReverseAndPrint(stringArray);
 
 
            Simple.ReverseAndPrint<double>(doubleArray);
            Simple.ReverseAndPrint(doubleArray);
 
            Console.ReadKey();
        }
    }
}
 
6.泛型结构
eg:实例说明一切
 
7.泛型委托
eg:没有返回值的实例
eg:有返回值的实例
 
8.泛型接口
eg:泛型接口实例
 
9泛型的协变和逆变
暂时没看,看不下
 
 
 
 
第20章 枚举数和迭代器
1.为什么数组可以用foreach迭代
为什么数组就可以使用foreach迭代呢?原因是数组可以提供一个叫做枚举数的对象.枚举数可以依次返回请求的数组的元素.
对于有枚举数的类型而言,必须有一个方法来获取它们,在.NET中获取一个对象枚举数的标准方法是调用对象的GetEnumerator方法.实现GetEnumerator方法的类型叫做可枚举类型.数组是可枚举类型.
 
2.枚举数类型
枚举数一共有3种:
●IEnumerator/IEnumerable接口——非泛型接口形式.
●IEnumerator<T>/IEnumerable<T>接口——泛型接口形式
●不使用接口形式.
 
3.使用IEnumerator接口
该接口包含三个函数成员:Current,MoveNext以及Reset.
●Current返回序列中当前位置项的属性.
●MoveNext是把枚举数位置前进到集合中下一项的方法,它返回布尔值,指示新的位置是有效位置或已经超过了序列的尾部.
●Reset方法把位置重置为原始状态.
eg:
using System;
using System.Collections;
 
namespace ConsolePractice
{
    class Program
    {
        static void Main()
        {
            int[] MyArray = { 10, 11, 12, 13 };//创建数组
 
            IEnumerator IE = MyArray.GetEnumerator();//获取枚举数
            while (IE.MoveNext())//移到下一项
            {
                int i = (int)IE.Current;//获取当前项
                Console.WriteLine("{0}", i);//输出
            }
            Console.ReadKey();
        }
    }
}
 
4.声明IEnumerator的枚举数
要创建非泛型接口的枚举数类,必须声明实现IEnumerator接口的类.IEnumerator接口的特性如下:
●它是System.Collenctions命名空间的成员.
●它包含3个方法Current,MoveNext和Reset.
 
5.IEnumerable接口
该接口只有一个成员——GetEnumberator方法,它返回对象的枚举数.
 
6.IEnumerable和IEnumerator示例
using System;
using System.Collections;
 
namespace ConsolePractice
{
    class ColorEnumerator : IEnumerator//继承IEnumerator接口就必须实现MoveNext(),Reset()方法和Current属性
    {
        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)
                {
                    throw new InvalidOperationException();
                }
                if (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;
        }
    }
 
    class MyColors : IEnumerable//继承了IEnumerable就必须实现GetEnumerator()方法.
    {
        string[] Colors = { "Red", "Yellow", "Blue" };
        public IEnumerator GetEnumerator()
        {
            return new ColorEnumerator(Colors);
        }
    }
 
    class Program
    {
        static void Main()
        {
            MyColors mc = new MyColors();
            foreach (string color in mc)
                Console.WriteLine(color);
            Console.ReadKey();
        }
    }
}
 
7.不实现接口的枚举数
 
8.泛型枚举接口
IEnumerable<T>和IEnumerator<T>
IEnumerator<T>接口
该接口另外两个接口继承——非泛型IEnumerator接口和IDisposable接口(IDisposable接口只有一个叫做Dispose的类型为void的无参方法,它可以用于释放由类占据的非托管资源),所以必须实现他们的成员
IEnumerable<T>接口
该泛型从IEnumerable继承,所以必须实现IEnumera接口的成员
 
9.迭代器
迭代器块有两个特殊语句
yield return语句执行了序列中返回的下一项
yield break语句指定在序列中没有更多项.
 
10.使用迭代器来创建枚举数
 
11.使用迭代器来创建可枚举类型
 
12.常见迭代器模式
 
13.产生多个可枚举类型和多个枚举数
P361~P363两个实例
 
 
 
 
第21章 介绍LINQ
1.匿名类型
这种形式的对象创建表达式由三部分组成:new关键字,类名或构造函数以及对象初始化器.
匿名类型只能和局部变量配合使用,不能用于类成员.
由于匿名类型没有名字,所以必须使用var关键词作为变量类型
eg:
 
2.查询方法和方法语法
查询方法:是声明形式的,看上去和SQL语句很相似,查询语法使用查询表达式形式书写.
方法语法:是命令形式的,它使用的是标准的方法调用.方法是一组叫做标准查询运算符的方法.
eg:
 
3.查询表达式的结构
from子句
form子句指定了要作为数据源使用的数据集合.
join子句
用于联结两个集合然后创建一个临时的对象集合.
let子句
let子句接受一个表达式的运算符并且把它赋值给一个需要在其他运算符中使用的标识符.
where子句
where子句根据之后的运算来去除不符合指定条件的项.
eg:
orderby子句
orderby子句接受一个表达式并根据表达式依次返回结果项.(排序)
select子句
可用于选择对象的某些字段,也可以用来创建匿名类型
eg:
group子句
group子句把select的对象根据一些标准进行分组.作为分组依据的项叫做键(key)
eg:
 
4.查询延续
eg:
using System;
using System.Linq;
 
namespace ConsolePractice
{
    class Program
    {
        public static void Main()
        {
            var groupA = new[] { 3, 4, 5, 6 };
            var groupB = new[] { 4, 5, 6, 7 };
 
            var someInts = from a in groupA
                           join b in groupB on a equals b
                           into groupAandB
                           from c in groupAandB//查询延续,将结果放入groupAaandB中
                           select c;
 
            foreach (var a in someInts)
                Console.Write("{0} ", a);
            Console.ReadKey();
        }
    }
}
 
5.标准查询运算符
标准查询运算符由一系列叫做API的方法组成.
System.Linq.Enumerable类声明了标准查询运算符方法.这些方法是扩展了IEnumerable<T>泛型的扩展方法.
由于运算符是扩展IEnumerable的扩展方法,所以它们必须满足下面语法条件
●必须声明为public或static
●必须在第一个参数前有this扩展指示器.
●必须把IEnumerable<T>作为第一个参数类型
eg:
using System;
using System.Linq;
using System.Collections;
 
namespace ConsolePractice
{
    class Program
    {
        public static void Main()
        {
            int[] intArray = new int[] { 3, 4, 5, 6, 7, 9 };
 
            var count1 = Enumerable.Count(intArray);//直接调用
            var firstnum1 = Enumerable.First(intArray);//直接调用
 
            var count2 = intArray.Count();//扩展方法调用(数组intArray作为被扩展的对象)
            var firstnum2 = intArray.First();//扩展方法调用
 
            Console.WriteLine("Count:{0},FirstNumber:{1}", count1, firstnum1);
            Console.WriteLine("Count:{0},FirstNumber:{1}", count2, firstnum1);
 
            Console.ReadKey();
        }
    }
}
 
6.委托参数
eg:这一节有点晕,找个适合重看吧
 
7.LINQ to XML
LINQ to XML API由很多表示XML树组件的类组成,其中最重要的三个类是:
XElement,XAttribute和XDocument.
除了XAttribute类,大多数用于创建XML树的类都从一个叫做XNode的类继承.
eg:创建,保存,加载,显示XML文档
 
8.XML树
补充:
Nodes方法:可以使用以类型作为参数的方法OfType(type)来指定返回某个类型的节点.
Elements方法:它是Nodes.OfType(XElement)()表达式的简写.该方法无参数时返回所有子XElements,使用单个name参数的Elements方法只返回具有这个名字的子XElements
Element方法:这个方法只获取当前节点的第一个子XElement.如果带参数,则获取第一个具有那个名字的子XElement.
eg:显示了Element和Elements方法:
 
9.XML的操作
eg:
 
10.使用XML属性
eg:添加,获取,移除,改变属性
using System;
using System.Xml.Linq;
 
namespace ConsolePractice
{
    class Program
    {
        public static void Main()
        {
            XDocument xd = new XDocument(
                new XElement("root",
                    new XAttribute("color","red"),//创建时添加属性
                    new XAttribute("size", "large"),//创建时添加属性
                    new XElement("first")
                    )
                );
 
 
            Console.WriteLine(xd);//显示XML树
            Console.WriteLine();//空行
 
 
            XElement rt=xd.Element("root");//获取元素
 
            XAttribute color = rt.Attribute("color");//获取属性
            XAttribute size = rt.Attribute("size");//获取属性
 
            Console.WriteLine("Color is {0}", color.Value);//显示属性值
            Console.WriteLine("Size is {0}", size.Value);//显示属性值
            Console.WriteLine();//空行
 
 
            rt.SetAttributeValue("size", "mediun");//改变属性值
            rt.SetAttributeValue("width","narrow");//添加属性,就是没有查找不到这个属性时,则添加这个属性
            Console.WriteLine(xd);//显示XML树
            Console.WriteLine();//空行
 
 
            rt.Attribute("color").Remove();//移除属性
            rt.SetAttributeValue("size", null);//移除属性,把某个属性设置为空就等于移除了.
            Console.WriteLine(xd);//显示XML树
 
            Console.ReadKey();
        }
    }
}
 
11.使用LINQ to XML的LINQ查询
eg:
饿死了......
 
 
 
 
第22章 同步与异步
再看吧
 
 
 
第23章 预处理指令
1.#define和#undef指令
#define指令声明一个编译符号
#undef指令取消定义一个编译符号
#define和#undef指令只能用在源文件的第一行,第一行!
 
2.条件编译
条件编译允许我们根据某个编译符号是否被定义标注一段代码被编译或跳过.
有4个指令可以用来指定条件编译:
#if
#else
#elif
#endif
 
3.诊断指令
诊断指令的字符串不需要被引号包围.
#error指令在#if结构中,因此只有符合#if指令的条件时才会生成消息.
#warning指令用于提醒程序员回头来清理这段代码.
 
4.行号指令
关键字#line
功能:
●改变由编译器警告和错误消息报告的出现行数;
●改变被编译器源文件的文件名;
●对交互式调试器隐藏一些行.
#line指令语法如下:
#line integer             //设置下一行值为整数的行的行号,integer表示行号 #line "filename"       //设置文件名 #line default            //重新保存实际的行号和文件名 #line hidden            //在断点调试器中隐藏代码 #line                         //停止在调试器中隐藏代码
 
5.区域指令
#region
#endregion
不解释了
 
6.#pragma warning指令
该指令允许我们关闭及重新开启警告消息
●.要关闭警告消息,可以使用disable加上逗号分隔的希望关闭的警告数列表的形式.
●.要重新开启警告消息,可以使用restore加上逗号分隔的希望关闭的警告数列表的形式.
eg:关闭了618和414的警告消息,开启了618的警告消息,若不带警告数字列表,则会应用于所有警告.
 
 
 
 
第24章 反射和特性
1.元数据和反射
●有关程序及其类型的数据被称为元数据,它们保存在程序的程序集中.
●程序在运行时,可以查看其它程序集或其本身的元数据.一个运行的程序查看本身的元数据或其他程序的元数据的行为叫做反射.
 
2.Type类
要使用反射,必须使用System.Reflection命名空间.
BCL声明了一个叫做Type的抽象类,它被设计用来包含类型的特性.
 
3.获取Type对象
object类型包含了一个方法叫做GetType方法,用于返回对实例Type对象的引用.
eg:
 
4.特性
特性是一种允许我们向程序的程序集增加元数据的语言结构,它用于保护程序结构信息的某种特殊类型的类.
●将应用了特性的程序结构叫做目标
●设计用来获取和使用元数据的程序被叫做特性的消费者
●.NET预定了很多特性,也可以自定义特性.
 
5.预定义的保留的特性
①Obsolete特性
该特性用于将程序标注为过期的并且在代码编译时显示有用的警告信息
eg:
 
②Conditional特性
该特性允许我们包括或排斥某个特定方法的所有调用.为方法声明引用Conditional特性并把编译符作为参数来使用.
●如果定义了编译符号,那么编译器会包含所有调用这个方法的代码,这和普通方法没有区别
●如果没有定义编译符号,则编译器会忽略代码中这个方法的所有调用.
eg:
 
6.预定义的特性
 
7.多个特性
可以为代码片段显示应用多个特性,有两种方式:等价的
 
8.特性目标
C#定义了10个标准的特性目标
 
9.声明自定义特性
P444~449没看,再看吧
 
 
 
 
第25章 其他主题
1.string类型的有用成员
 
2.使用StringBuilder类
该类可以动态,有效地产生字符串,并且避免创建许多副本.(string每一次修改都会产生副本,因为字符串是不可变,只能重建)
 
3.格式化数字字符串
语法如图:由索引号,对齐说明符和格式说明符组成
对齐说明符特性如下:
●可选的,用逗号来和索引号分离
●由一个正整数或负整数组成.整数部分表示字段使用字符最少数量,符号表示左对齐还是右对齐,正数表示右对齐,负数表示左对齐.
格式组件:分为两部分
●格式说明符:看下表
●精度说明符:可选,由1~2为数字组成,它的意义取决于格式说明符
eg:
 
4.把字符串解析为数据值.
所有预定义的简单类型都有一个叫做Parse的静态方法,它接受一个表示这个类型的字符串,并且把它转换为类型的实际值.
eg:
Parse方法的缺点是如果不能把string成功转换为目标类型的话会抛出一个异常.而TryParse方法可以避免这个问题.
TryParse方法接受两个参数并返回一个bool值
●第一个参数是希望转换的字符串.
●第二个参数是指向目标类型变量的引用的out参数.
●如果TryParse成功,返回true,否则返回false.
eg:
 
5.可空类型
●可以从任何值类型创建可空类型,包括预定义的简单类型.
●不能从引用类型或其他类型创建可空类型
●不能在代码中显示声明可空类型,只能说明可空类型的变量.
可空类型的几个重要的属性:
●HasValue属性是bool类型,并且指示值是否有效.
●value属性是和基础类型相同的类型,并且返回变量的值
eg:
使用空接合运算符
空接合运算符允许可空类型变量为null时返回一个值给表达式.
●第一个操作数可空类型的变量
●第二个是相同基础类型的不可空值.
●如果第一个操作数运算符后为null,那么第二个操作数就会被返回作为运算符结果.
eg:
 
6.可空用户自定义类型
可空用户自定义类型不会直接暴露基础类型的任何成员,只通过可空类型的Value属性暴露.
eg:看图,基础类型成员不可以被直接访问的.
 
 

【C#4.0图解教程】笔记(第19章~第25章)的更多相关文章

  1. 【读书笔记】关于《精通C#(第6版)》与《C#5.0图解教程》中的一点矛盾的地方

    志铭-2020年2月8日 03:32:03 先说明,这是一个旧问题,很久很久以前大家就讨论了, 哈哈哈,而且先声明这是一个很无聊的问题,

  2. JavaScript高级程序设计(第三版)学习笔记22、24、25章

    第22章,高级技巧 高级函数 安全的类型检测 typeof会出现无法预知的行为 instanceof在多个全局作用域中并不能正确工作 调用Object原生的toString方法,会返回[Object ...

  3. 【C#4.0图解教程】笔记(第9章~第18章)

    第9章 语句 1.标签语句 ①.标签语句由一个标识符后面跟着一个冒号再跟着一条语句组成 ②.标签语句的执行完全如同标签不存在一样,并仅执行冒号后的语句. ③.给语句添加一个标签允许控制从代码的另一部分 ...

  4. 【C#4.0图解教程】笔记(第1章~第8章)

    第1章 C#和.NET框架 1..NET框架的组成 .NET框架由三部分组成(严格来说只有CLR和FCL(框架类库)两部分),如图 执行环境称为:CLR(公共语言运行库),它在运行期管理程序的执行. ...

  5. C#4.0图解教程 - 第24章 反射和特性 – 2.特性

    1.特性 定义 Attribute用来对类.属性.方法等标注额外的信息,贴一个标签(附着物) 通俗:给 类 或 类成员 贴一个标签,就像航空部为你的行李贴一个标签一样 注意,特性 是 类 和 类的成员 ...

  6. C#4.0图解教程 - 第24章 反射和特性 - 1.反射

    24.1 元数据和反射 有关程序及类型的数据被成为 元数据.他们保存在程序集中. 程序运行时,可以查看其他程序集或其本身的元数据.一个运行的程序查看本身元数据或其他程序的元数据的行为叫做 反射. 24 ...

  7. 黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (高级)

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (高级) 本章介绍的是企业库加密应用程序模块 ...

  8. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  9. 《C#图解教程》读书笔记之五:委托和事件

    本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.委托初窥:一个拥有方法的对象 (1)本质:持有一个或多个方法的对象:委托和典型的对象不同,执行委托实际上是执 ...

随机推荐

  1. java对象和类学习

    定义对象的类: 一个对象的状态(属性或特征)是指那些具有他们当前值的数据域 一个对象的行为是由方法定义的,调用对象的方法就是完成对象的一个动作 使用一个通用类来定义同一类型的对象.类是一个模板,一个对 ...

  2. leetcode@ [87] Scramble String (Dynamic Programming)

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...

  3. 射频识别技术漫谈(5)——防冲突【worldsing 笔记】

    正常情况下读写器某一时刻只能对磁场中的一张射频卡进行读写操作.但是当多张卡片同时进入读写器的射频场时,读写器怎么办呢?读写器需要选出唯一的一张卡片进行读写操作,这就是防冲突. 防冲突机制是非接触式智能 ...

  4. IAR 1.3 for STM8 ST-Link无法调试 无法仿真 the debugging session could not be started

    IAR 1.3 for STM8 ST-Link无法调试 the debugging session could not be started CPU型号是:STM8F103F3 首先要用ST Vis ...

  5. MVC上传文件目录至共享目录

    1.需在共享目录的服务器上加入一个有权限(所有权限,包括读.写.删除等权限)的账号名2.MVC站点webconfig文件中,<system.web>节点中加入配置节点,    <id ...

  6. 《Effect Java》 归纳总结

    目录: 一.创建和销毁对象 (1 ~ 7) 二.对于所有对象都通用的方法 (8 ~ 12) 三.类和接口 (13 ~ 22) 四.泛型 (23 ~ 29) 五.枚举和注解 (30 ~ 37) 六.方法 ...

  7. vs2015 配置opencv3.0遇到的问题

    1.问题 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C2872 "ACCESS_MASK": 不明确的符号 FaceFeature_GSF C:\Program Fi ...

  8. iOS- iPad UIPopoverController

    在IPAD开发中,有一个很有趣的视图控制器,UIPopoverControllr,它的初始化必须要设置一个"内容视图",相当于它本身只是作为一个“容器”,而显示的内容还需要另外一个 ...

  9. 【52】写了placement new也要写placement delete

    1.Widget* pw = new Widget; 调用了两个方法:第一个方法是operator new 负责分配内存:第二个方法是在分配的内存上构造Widget,即调用Widget的default ...

  10. 眼下最好的JSP分页技术

     2005-08-24   来源:CSDN  作者:wanchao2001 前言     在使用数据库的过程中,不可避免的须要使用到分页的功能,但是JDBC的规范对此却没有非常好的解决.对于这个需求非 ...