精华内容
下载资源
问答
  • c# 7.0 本质论 随书 代码 资源 代码例子 压缩包 光盘
  • 新书推荐《C# 7.0本质论》点击上图了解及购买全面且专业的C#编程指南,经典畅销书最新升级,涵盖C# 7.0,世界级C#专家亲笔撰写,微软C#项目经理作序推荐。内容简介作为历年来深受各...

    新书推荐

    C# 7.0本质论

    点击上图了解及购买

    全面且专业的C#编程指南,经典畅销书最新升级,涵盖C# 7.0,世界级C#专家亲笔撰写,微软C#项目经理作序推荐。

    内容简介

    作为历年来深受各层次开发人员欢迎的C#指南,本书讨论了从C# 3.0到7.0的*重要的C#特性,强调了现代编程模式,可帮助读者编写简洁、强大、健壮、安全和易于维护的C#代码。世界级C#专家Mark Michaelis对语言进行了全面而深入的探讨,提供了对关键C# 7.0增强、C# 7.0和.NET Core/.NET Standard的配合使用以及跨平台编译的专业论述。

    作者简介

    Mark Michaelis是高端软件工程和咨询公司IntelliTect的创办者、首席技术架构师和培训师。Mark经常在开发者大会上发言,写过许多文章和书籍,目前是《MSDN Magazine》的《Essential .NET》专栏作家。

    从1996年起,他一直是C#、Visual Studio Team System和Windows SDK的MVP。2007年被评选为微软的Regional Director。他还服务于微软的几个软件设计评审团队,包括C#和VSTS。

    Mark拥有伊利诺伊大学哲学专业文学学士学位和伊利诺伊理工大学计算机硕士学位。

    他不是痴迷于计算机,就是忙于陪伴家人或者玩壁球(2016年暂停铁人三项训练)。他居住在华盛顿州的斯波坎,他和妻子Elisabeth有三个孩子:Benjamin、Hanna和Abigail。

    技术编辑简介

    Eric Lippert目前在Facebook负责开发者工具。之前是微软C#语言设计团队的一员。不在StackOverflow上回答用户的C#问题或者编辑程序书时,他总是喜欢玩他的小帆船。目前和妻子Leah居住在华盛顿州的西雅图。

    目录

    译者序

    推荐序

    前言

    致谢

    作者简介

    第1章 C#概述  / 1

    1.1 Hello, World   / 1

    1.2 C#语法基础  / 8

    1.3 使用变量  / 14

    1.4 控制台输入和输出  / 17

    1.5 注释  / 20

    1.6 托管执行和CLI  / 22

    1.7 多个.NET框架  / 26

    1.8 小结  / 28

    第2章 数据类型  / 29

    2.1 基本数值类型  / 29

    2.2 更多基本类型  / 36

    2.3 null和void  / 46

    2.4 数据类型转换  / 47

    2.5 小结  / 52

    第3章 更多数据类型  / 53

    3.1 类型的划分  / 53

    3.2 可空修饰符  / 55

    3.3 元组  / 57

    3.4 数组  / 62

    3.5 小结  / 74

    第4章 操作符和控制流程  / 75

    4.1 操作符  / 75

    4.2 控制流程概述  / 87

    4.3 代码块({})  / 91

    4.4 代码块、作用域和声明空间  / 93

    4.5 布尔表达式  / 94

    4.6 按位操作符(<<,>>,|,&,^,~)  / 101

    4.7 控制流程语句(续)  / 106

    4.8 跳转语句  / 115

    4.9 C#预处理器指令  / 119

    4.10 小结  / 124

    第5章 方法和参数  / 126

    5.1 方法的调用  / 127

    5.2 方法的声明  / 131

    5.3 using指令  / 135

    5.4 Main()的返回值和参数  / 139

    5.5 高级方法参数  / 141

    5.6 递归  / 149

    5.7 方法重载  / 152

    5.8 可选参数  / 154

    5.9 用异常实现基本错误处理  / 157

    5.10 小结  / 168

    第6章 类  / 169

    6.1 类的声明和实例化  / 172

    6.2 实例字段  / 174

    6.3 实例方法  / 176

    6.4 使用this关键字  / 177

    6.5 访问修饰符  / 183

    6.6 属性  / 184

    6.7 构造函数  / 197

    6.8 静态成员  / 205

    6.9 扩展方法  / 213

    6.10 封装数据  / 214

    6.11 嵌套类  / 216

    6.12 分部类  / 218

    6.13 小结  / 222

    第7章 继承  / 223

    7.1 派生  / 224

    7.2 重写基类  / 232

    7.3 抽象类  / 242

    7.4 所有类都从System.Object派生  / 246

    7.5 使用is操作符验证基础类型  / 247

    7.6 用is操作符进行模式匹配  / 248

    7.7 switch语句中的模式匹配  / 248

    7.8 使用as操作符进行转换  / 250

    7.9 小结  / 251

    第8章 接口  / 252

    8.1 接口概述  / 253

    8.2 通过接口实现多态性  / 254

    8.3 接口实现  / 258

    8.4 在实现类和接口之间转换  / 262

    8.5 接口继承  / 263

    8.6 多接口继承  / 265

    8.7 接口上的扩展方法  / 265

    8.8 通过接口实现多继承  / 266

    8.9 版本控制  / 269

    8.10 比较接口和类  / 270

    8.11 比较接口和特性  / 271

    8.12 小结  / 271

    第9章 值类型  / 272

    9.1 结构  / 275

    9.2 装箱  / 279

    9.3 枚举  / 285

    9.4 小结  / 293

    第10章 合式类型  / 295

    10.1 重写object的成员  / 295

    10.2 操作符重载  / 305

    10.3 引用其他程序集  / 311

    10.4 定义命名空间  / 318

    10.5 XML注释  / 320

    10.6 垃圾回收  / 323

    10.7 资源清理  / 325

    10.8 推迟初始化  / 332

    10.9 小结  / 333

    第11章 异常处理  / 334

    11.1 多异常类型  / 334

    11.2 捕捉异常  / 336

    11.3 常规catch块  / 339

    11.4 异常处理规范  / 341

    11.5 自定义异常  / 343

    11.6 重新抛出包装的异常  / 346

    11.7 小结  / 349

    第12章 泛型  / 350

    12.1 如果C#没有泛型  / 350

    12.2 泛型类型概述  / 355

    12.3 约束  / 364

    12.4 泛型方法  / 374

    12.5 协变性和逆变性  / 377

    12.6 泛型的内部机制  / 382

    12.7 小结  / 385

    第13章 委托和Lambda表达式  / 386

    13.1 委托概述  / 387

    13.2 声明委托类型  / 390

    13.3 Lambda表达式  / 396

    13.4 匿名方法  / 401

    13.5 小结  / 413

    第14章 事件  / 414

    14.1 使用多播委托编码Publish-Subscribe模式  / 415

    14.2 理解事件  / 426

    14.3 小结  / 435

    第15章 支持标准查询操作符的集合接口  / 436

    15.1 集合初始化器  / 437

    15.2 IEnumerable<T>使类成为集合  / 439

    15.3 标准查询操作符  / 444

    15.4 匿名类型之于LINQ   / 470

    15.5 小结  / 477

    第16章 使用查询表达式的LINQ  / 478

    16.1 查询表达式概述  / 478

    16.2 查询表达式只是方法调用  / 493

    16.3 小结  / 494

    第17章 构建自定义集合  / 496

    17.1 更多集合接口  / 497

    17.2 主要集合类  / 498

    17.3 提供索引器  / 512

    17.4 返回null或者空集合  / 515

    17.5 迭代器  / 515

    17.6 小结  / 527

    第18章 反射、特性和动态编程  / 528

    18.1 反射  / 528

    18.2 特性  / 539

    18.3 使用动态对象进行编程  / 557

    18.4 小结  / 565

    第19章 多线程处理  / 566

    19.1 多线程处理基础  / 568

    19.2 使用System.Threading  / 572

    19.3 异步任务   / 577

    19.4 取消任务  / 591

    19.5 基于任务的异步模式  / 596

    19.6 并行迭代  / 618

    19.7 并行执行LINQ查询  / 626

    19.8 小结  / 630

    第20章 线程同步  / 631

    20.1 线程同步的意义  / 632

    20.2 计时器  / 653

    20.3 小结  / 655

    第21章 平台互操作性和不安全代码  / 656

    21.1 平台调用  / 657

    21.2 指针和地址  / 667

    21.3 通过委托执行不安全代码  / 674

    21.4 小结  / 676

    第22章 公共语言基础结构  / 677

    22.1 CLI的定义  / 677

    22.2 CLI的实现  / 678

    22.3 .NET Standard  / 680

    22.4 BCL  / 681

    22.5 将C#编译成机器码  / 681

    22.6 运行时  / 682

    22.7 程序集、清单和模块  / 685

    22.8 公共中间语言  / 687

    22.9 公共类型系统  / 687

    22.10 公共语言规范  / 688

    22.11 元数据  / 688

    22.12 .NET Native和AOT编译  / 689

    22.13 小结  / 689

    你与世界

    只差一个

    公众号

    展开全文
  • 新书推荐《C# 7.0本质论(英文版)》世界级的C#专家经典畅销书!入门及进阶的进阶之作!涵盖最新的C# 7.0编辑推荐本书是经典畅销书,前几版广受好评;作者是世界级的C#专家,长期的微...

    新书推荐

    C# 7.0本质论(英文版)

    世界级的C#专家经典畅销书!入门及进阶的进阶之作!涵盖最新的C# 7.0

    编辑推荐

    • 本书是经典畅销书,前几版广受好评;

    • 作者是世界级的C#专家,长期的微软MVP和Regional Director;

    • 微软C#项目经理鼎力推荐

    • 涵盖最新的C# 7.0

    内容简介

    本书共22章。第1章是C#概述;第2章和第3章介绍C#中的数据类型;第4章讨论操作符和控制流;第5章探讨方法和参数;第6章讲解类,它是面向对象技术的核心;第7章介绍继承,其中包括继承语法的细节;第8章探讨接口;第9章和第10章分别介绍值类型和合式类型;第11章延伸讨论第5章引入的异常处理机制;第12章引入泛型;第13章讲解委托和Lambda表达式;第14章讨论事件;第15章介绍支持标准查询操作符的集合接口;第16章探讨使用查询表达式的LINQ;第17章讲解如何构建自定义集合;第18章介绍反射、特性和动态编程的方方面面;第19章涵盖多线程处理;第20章以第19章为基础,演示了线程同步的用法;第21章涵盖平台互操作性和不安全的代码;第22章讲解公共语言基础结构,并讨论C#程序与底层“运行时”及规范的关系。

    作者简介

    Mark Michaelis是高端软件工程和咨询公司IntelliTect的创办者、首席技术架构师和培训师。Mark经常在开发者大会上发言,写过许多文章和书籍,目前是《MSDN Magazine》的《Essential .NET》专栏作家。

    本书是C#最权威、最值得尊重的参考书之一,作者为此付出了非凡的努力!Mark Michaelis的《Essential C#》系列多年来一直是畅销经典。而我刚认识Mark的时候,这本书还处于萌芽阶段。

    2005年LINQ(语言集成查询,Language Integrated Query)公布时,我才刚加入微软公司,正好见证了PDC会议上令人激动的公开发布时刻。虽然我对技术本身几乎没有什么贡献,但它的宣传造势我可是全程参加了。那时人人都在谈论它,宣传小册子满天飞。那是C#和.NET的大日子,至今依然令人难忘。

    但会场的实践实验室区域却相当安静,那儿的人可以按部就班地试验处于预览阶段的技术。我就是在那儿遇见Mark的。不用说,他一点儿都没有按部就班的意思。他在做自己的试验,梳理文档,和别人沟通,忙着鼓捣自己的东西。

    作为C#社区的新人,我感觉自己在那次会议上见到了许多人。但老实说,当时太混乱了,我唯一记得清的就是Mark。因为当问他是否喜欢这个新技术时,他不像别人那样马上开始滔滔不绝,而是非常冷静地说:“还不确定,要自己搞一搞才知道。”他希望完整地理解并消化一种技术,之后才将自己的想法告知于人。

    所以我们之间没像我本来设想的那样发生一次快餐式的对话。相反,我们的对话相当坦诚、颇有营养。像这样的交流好多年都没有过了。新技术的细节、造成的后果和存在的问题全都涉及了。对我们这些语言设计者而言,Mark是最有价值的社区成员。他非常聪明,善于打破砂锅问到底,能深刻理解一种技术对于真正的开发人员的影响。但是,最根本的原因可能还是他坦诚,他从不惧怕说出自己的想法。一样东西通过了Mark的测试,就没什么好担心的了!

    这些特质也使Mark成为一名出色的作家。他的文字直指技术的本质,敏锐地指出技术的真正价值和问题,向读者提供最完整的信息且没有废话。没人能像这位大师一样帮你正确理解C# 7.0。

    请好好享用本书!

    ——Mads Torgersen,微软公司C#项目经理

    目录

    第1章 C#概述 1

    1.1 Hello, World 2

    1.2 C#语法基础 11

    1.3 使用变量 20

    1.4 控制台输入和输出 24

    1.5 注释 28

    1.6 托管执行和CLI 32

    1.7 多个.NET框架 37

    第2章 数据类型 43

    2.1 基本数值类型 44

    2.2 更多基本类型 53

    2.3 null和void 67

    2.4 数据类型转换 69

    第3章 更多数据类型 77

    3.1 类型的划分 77

    3.2 可空修饰符 80

    3.3 元组 83

    3.4 数组 90

    第4章 操作符和控制流程 109

    4.1 操作符 110

    4.2 控制流程概述 126

    4.3 代码块 132

    4.4 代码块、作用域和声明空间 135

    4.5 布尔表达式 137

    4.6 按位操作符 147

    4.7 控制流程语句(续) 153

    4.8 跳转语句 165

    4.9 C#预处理器指令 171

    第5章 方法和参数 181

    5.1 调用方法 182

    5.2 声明方法 189

    5.3 using指令 195

    5.4 Main()的返回值和参数 200

    5.5 高级方法参数 203

    5.6 递归 215

    5.7 方法重载 217

    5.8 可选参数 220

    5.9 用异常实现基本错误处理 225

    第6章 类 241

    6.1 类的声明和实例化 245

    6.2 实例字段 249

    6.3 实例方法 251

    6.4 使用this关键字 252

    6.5 访问修饰符 259

    6.6 属性 261

    6.7 构造函数 278

    6.8 静态成员 289

    6.9 扩展方法 299

    6.10 封装数据 301

    6.11 嵌套类 304

    6.12 分部类 307

    第7章 继承 313

    7.1 派生 314

    7.2 重写基类 326

    7.3 抽象类 338

    7.4 所有类都从System.Object派生 344

    7.5 使用is操作符验证基础类型 345

    7.6 使用is操作符进行模式匹配 346

    7.7 switch语句中的模式匹配 347

    7.8 使用as操作符进行转换 349

    第8章 接口 353

    8.1 接口概述 354

    8.2 通过接口实现多态性 355

    8.3 接口实现 360

    8.4 在实现类和接口之间转换 366

    8.5 接口继承 366

    8.6 多接口继承 369

    8.7 接口上的扩展方法 369

    8.8 通过接口实现多继承 371

    8.9 版本控制 374

    8.10 比较接口和类 375

    8.11 比较接口和特性 377

    第9章 值类型 379

    9.1 结构 383

    9.2 装箱 390

    9.3 枚举 398

    第10章 合式类型 411

    10.1 重写object的成员 411

    10.2 操作符重载 424

    10.3 引用其他程序集 432

    10.4 定义命名空间 442

    10.5 XML注释 445

    10.6 垃圾回收 449

    10.7 资源清理 452

    10.8 推迟初始化 461

    第11章 异常处理 465

    11.1 多异常类型 465

    11.2 捕捉异常 469

    11.3 常规catch块 473

    11.4 异常处理规范 475

    11.5 自定义异常 479

    11.6 重新抛出包装的异常 483

    第12章 泛型 487

    12.1 如果C#没有泛型 488

    12.2 泛型类型概述 493

    12.3 约束 506

    12.4 泛型方法 519

    12.5 协变性和逆变性 524

    12.6 泛型的内部机制 531

    第13章 委托和Lambda表达式 537

    13.1 委托概述 538

    13.2 声明委托类型 542

    13.3 Lambda表达式 550

    13.4 匿名方法 556

    第14章 事件 575

    14.1 使用多播委托编码Publish-Subscribe模式 576

    14.2 理解事件 591

    第15章 支持标准查询操作符的集合接口 603

    15.1 集合初始化器 604

    15.2 IEnumerable<T>使类成为集合 607

    15.3 标准查询操作符 613

    15.4 匿名类型之于LINQ 646

    第16章 使用查询表达式的LINQ 657

    16.1 查询表达式概述 658

    16.2 查询表达式只是方法调用 676

    第17章 构建自定义集合 679

    17.1 更多集合接口 680

    17.2 主要集合类 683

    17.3 提供索引器 702

    17.4 返回null或者空集合 705

    17.5 迭代器 705

    第18章 反射、特性和动态编程 721

    18.1 反射 722

    18.2 特性 735

    18.3 使用动态对象进行编程 759

    第19章 多线程处理 771

    19.1 多线程处理基础 774

    19.2 使用System.Threading 781

    19.3 异步任务 789

    19.4 取消任务 810

    19.5 基于任务的异步模式 816

    19.6 并行迭代 846

    19.7 并行执行LINQ查询 856

    第20章 线程同步 863

    20.1 线程同步的意义 864

    20.2 计时器 893

    第21章 平台互操作性和不安全代码 897

    21.1 平台调用 898

    21.2 指针和地址 910

    21.3 通过委托执行不安全代码 920

    第22章 公共语言基础结构(CLI) 923

    22.1 CLI的定义 924

    22.2 CLI的实现 925

    22.3 .NET标准 928

    22.4 BCL 929

    22.5 C#编译成机器码 929

    22.6 运行时 932

    22.7 程序集、清单和模块 936

    22.8 公共中间语言 939

    22.9 公共类型系统 939

    22.10 公共语言规范 940

    22.11 元数据 941

    22.12 NET Native和AOT编译 942

    Contents

    1 Introducing C# 1

    Hello, World 2

    C# Syntax Fundamentals 11

    Working with Variables 20

    Console Input and Output 24

    Commne ts  28

    Managed Execution and the Common Language Infrastructure 32

    Multiple .NET Frameworks 37

    2 Data Types 43Fundamental Numeric Types 44

    More Fundamental Types 53

    null and void 67

    Conversions between Data Types 69

    3 More with Data Types 77

    Categories of Types 77

    Nullable Modifier 80

    Tuples 83

    Arrays 90

    4 Operators and Control Flow 109

    Operators 110

    Introducing Flow Control 126

    Code Blocks ({}) 132

    Code Blocks, Scopes, and Declaration Spaces 135

    Boolean Expressions 137

    Bitwise Operators (<<, >>, |, &, ^, ~) 147

    Control Flow Statements, Continued 153

    Jump Statements 165

    C# Preprocessor Directives 171

    5 Methods and Parameters 181

    Calling a Method 182

    Declaring a Method 189

    The using Directive 195

    Returns and Parameters on Main() 200

    Advanced Method Parameters 203

    Recursion 215

    Method Overloading 217

    Optional Parameters 220

    Basic Error Handling with Exceptions 225

    6 Classes 241

    Declaring and Instantiating a Class 245

    Instance Fields 249

    Instance Methods 251

    Using the this Keyword 252

    Access Modifiers 259

    Properties 261

    Constructors 278

    Static Members 289

    Extension Methods 299

    Encapsulating the Data 301

    Nested Classes 304

    Partial Classes 307

    7 Inheritance 313

    Derivation 314

    Overriding the Base Class 326

    Abstract Classes 338

    All Classes Derive from System.Object 344

    Verifying the Underlying Type with the is Operator 345

    Pattern Matching with the is Operator 346

    Pattern Matching within a switch Statement 347

    Conversion Using the as Operator 349

    8 Interfaces 353

    Introducing Interfaces 354

    Polymorphism through Interfaces 355

    Interface Implementation 360

    Converting between the Implementing Class and Its Interfaces 366

    Interface Inheritance 366

    Multiple Interface Inheritance 369

    Extension Methods on Interfaces 369

    Implementing Multiple Inheritance via Interfaces 371

    Versioning 374

    Interfaces Compared with Classes 375

    Interfaces Compared with Attributes 377

    9 Value Types 379

    Structs 383

    Boxing 390

    Enums 398

    10 Well-Formed Types 411

    Overriding object Members 411

    Operator Overloading 424

    Referencing Other Assemblies 432

    Defining Namespaces 442

    XML Comments 445

    Garbage Collection 449

    Resource Cleanup 452

    Lazy Initialization 461

    11 Exception Handling 465

    Multiple Exception Types 465

    Catching Exceptions 469

    General Catch Block 473

    Guidelines for Exception Handling 475

    Defining Custom Exceptions 479

    Rethrowing a Wrapped Exception 483

    12 Generics 487

    C# without Generics 488

    Introducing Generic Types 493

    Constraints 506

    Generic Methods 519

    Covariance and Contravariance 524

    Generic Internals 531

    13 Delegates and Lambda Expressions 537

    Introducing Delegates 538

    Declaring Delegate Types 542

    Lambda Expressions 550

    Anonymous Methods 556

    14 Events 575

    Coding the Publish-Subscribe Pattern with Multicast Delegates 576

    Understanding Events 591

    15 Collection Interfaces with Standard Query Operators 603

    Collection Initializers 604

    What Makes a Class a Collection: IEnumerable<T> 607

    Standard Query Operators 613

    Anonymous Types with LINQ 646

    16 LINQ with Query Expressions 657

    Introducing Query Expressions 658

    Query Expressions Are Just Method Invocations 676

    17 Building Custom Collections 679

    More Collection Interfaces 680

    Primary Collection Classes 683

    Providing an Indexer 702

    Returning Null or an Empty Collection 705

    Iterators 705

    18 Reflection, Attributes, and Dynamic Programming 721

    Reflection 722

    Attributes 735

    Programming with Dynamic Objects 759

    19 Multithreading 771

    Multithreading Basics 774

    Working with System.Threading 781

    Asynchronous Tasks 789

    Canceling a Task 810

    The Task-based Asynchronous Pattern 816

    Executing Loop Iterations in Parallel 846

    Running LINQ Queries in Parallel 856

    20 Thread Synchronization 863

    Why Synchronization? 864

    Timers 893

    21 Platform Interoperability and Unsafe Code 897

    Platform Invoke 898

    Pointers and Addresses 910

    Executing Unsafe Code via a Delegate 920

    22 The Common Language Infrastructure 923

    Defining the Common Language Infrastructure 924

    CLI Implementations 925

    .NET Standard 928

    Base Class Library 929

    C# Compilation to Machine Code 929

    Runtime 932

    Assemblies, Manifests, and Modules 936

    Common Intermediate Language 939

    Common Type System 939

    Common Language Specification 940

    Metadata 941

    .NET Native and Ahead of Time Compilation 942

    ~活动~

    试读章节写书评赢取赠书

    点击“阅读原文”登陆《C# 7.0本质论(英文版)》试读页面,试读章节后写下本书对你的帮助或启发,字数不得少于50字;即有机会获得赠书一本,共5本。

    你与世界

    只差一个

    公众号

    “阅读原文”一起来了解吧!

    展开全文
  • 本资源适合初学者,以及有一定基础的,是不可多得资源
  • 文章目录C#概述C#语法基础标识符类型定义使用变量变量的声明注释数据类型基本数值类型整数类型字面值更多基本类型字符串更多数据类型可空修饰符隐式类型的局部变量元组操作符和控制流程操作符二元算术操作符(+,-,...

    文章目录

    C#概述

    C#语法基础

    标识符

    • 要更注重标识符的清晰而不是简短。
    • 不要在标识符名称中使用单词缩写。
    • 不要使用不被广泛接受的首字母缩写词,即使被广泛接受,非必要也不要用。

    • 要把两个字母的首字母缩写词全部大写,除非它是camelCase标识符的第一个单词。
    • 包含三个或更多字母的首字母缩写词,仅第一个字母才要大写, 除非该缩写词是camelCase标识符的第一个单词
    • 在camelCase标识符开头的首字母缩写词中,所有字母都不要大写。
    • 不要使用匈牙利命名法(不要为变量名称附加类型前缀)。

    类型定义

    • 要用名词或名词短语命名类。

    • 要为所有类名使用PascalCase大小写风格。

    使用变量

    变量的声明

    • 要为局部变量使用camelCase风格命名。

    注释

    • 不要使用注释,除非代码本身“一言难尽”。
    • 要尽量写清楚的代码而不是通过注释澄清复杂的算法。

    数据类型

    基本数值类型

    整数类型

    • 要在指定数据类型时使用C#关键字而不是BCL名称(例如,使用string而不是String)。
    • 要一致而不要变来变去。

    字面值

    • 要使用大写的字面值后缀(例如1.618033988749895M)

    更多基本类型

    字符串

    • 要依赖 System.WriteLine()System.Environment.NewLine 而不是 \n 来确保跨平台兼容。

    更多数据类型

    可空修饰符

    隐式类型的局部变量

    • 避免使用隐式类型的局部变量,除非所赋的值的数据类型显而易见。

    元组

    • 要为元组语法的变量声明使用camelCase大小写规范。
    • 考虑为所有元组项名称使用PascalCase大小写风格。

    操作符和控制流程

    操作符

    二元算术操作符(+,-,*,/,%)

    • 要用圆括号增加代码的易读性,尤其是在操作符优先级不是让人一目了然的时候。

    • 要在字符串可能会本地化时用复合格式化而不是加法操作符来连接字符串。

    • 避免在需要准确的十进制小数算术运算时使用二进制浮点类型,改为使用decimal浮点类型。

    • 避免将二进制浮点类型用于相等性条件式。要么判断两个值之差是否在容差范围之内,要么使用decimal类型。

    递增和递减操作符(++,–)

    • 避免递增和递减操作符的使用让人迷惑。
    • 在C、C++和C#之间移植使用了递增和递减操作符的代码要小心;C和C++的实现遵循的不一定是和C#相同的规则。

    常量表达式和常量符号

    • 不要用常量表示将来可能改变的任何值。π和金原子的质子数是常量。金价、公司名和程序版本号则应该是变量。

    代码块

    • 除非最简单的单行if语句,否则避免省略大括号

    布尔表达式

    条件操作符(?:)

    • 考虑使用if/else语句而不是过于复杂的条件表达式。

    控制流程语句(续)

    for循环

    • 如果被迫要写包含复杂条件和多个循环变量的for循环,考虑重构方法使控制流程更容易理解。

    • 事先知道循环次数,且循环中要用到控制循环次数的“计数器”,要使用for循环。
    • 事先不知道循环次数而且不需要计数器,要使用while循环。

    基本switch语句

    • 不要使用continue作为跳转语句退出switch小节。如switch在循环中,这样写合法。但很容易对之后的switch小节中出现的break产生困惑。

    跳转语句

    goto语句

    • 避免使用goto

    方法和参数

    方法的调用

    • 要为方法名使用动词或动词短语。

    命名空间

    • 要为命名空间使用PascalCase大小写。
    • 考虑组织源代码文件目录结构以匹配命名空间层次结构。

    方法的声明

    参数声明

    • 要为参数名使用camelCase大小写。

    高级方法参数

    参数数组(params)

    • 方法能处理任何数量(包括零个)额外实参时要使用参数数组。

    可选参数

    • 要尽量为所有参数提供好的默认值。
    • 要提供简单的方法重载,必须的参数的数量要少。
    • 考虑从最简单到最复杂组织重载。

    • 要将参数名视为API的一部分;要强调API之间的版本兼容性,就避免改变名称。

    用异常实现基本的错误处理

    捕捉错误

    • 避免从finally块显式抛出异常(因方法调用而隐式抛出的异常可以接受)。
    • 要优先使用try/finally而不是try/catch块来实现资源清理代码。
    • 要在抛出的异常中描述异常为什么发生。顺带说明如何防范更佳。

    • 避免使用常规catch块,用捕捉System.Exception的catch块代替。
    • 避免捕捉无法从中完全恢复的异常。这种异常未处理比不正确处理好。
    • 避免在重新抛出前捕捉和记录异常。要允许异常逃脱(传播),直至它被正确处理。

    使用throw语句报告错误

    • 要在捕捉并重新抛出异常时使用空的throw语句,以便保留调用栈。
    • 要通过抛出异常而不是返回错误码来报告执行失败。
    • 不要让公共成员将异常作为返回值或者out参数。抛出异常来指明错误;不要把它们作为返回值来指明错误。

    • 不要用异常处理正常的、预期的情况;用它们处理异常的、非预期的情况。

    类的声明和实例化

    • 不要在一个源代码文件中放多个类。
    • 要用所含公共类型的名称命名源代码文件。

    属性

    属性和字段的设计规范

    • 要使用属性简化对简单数据的访问(只进行简单计算)。

    • 避免从属性取值方法抛出异常。

    • 要在属性抛出异常时保留原始属性值。

    • 如果不需要额外逻辑,要优先使用自动实现的属性,而不是属性加简单支持字段。


    • 考虑为支持字段和属性使用相同的大小写风格,为支持字段附加“_”前缀。但不要使用双下划线,它是为 C# 编译器保留的。

    • 要使用名词、名词短语或形容词命名属性。

    • 考虑让某个属性和它的类型同名。

    • 避免用 camelCase 大小写风格命名字段。

    • 如果有意义的话,要为 Boolean 属性附加 ”Is“ “Can”“Has” 前缀。

    • 不要声明 publicprotected 实例字段(而是通过属性公开)。

    • 要用 PascalCase 大小写风格命名属性。

    • 要优先使用自动实现的属性而不是字段。

    • 如果没有额外的实现逻辑,要优先使用自动实现的属性而不是自己写完整版本。

    提供属性验证

    • 避免从属性外部(即使是从属性所在的类中)访问属性的支持字段。
    • 创建 ArgumentException()ArgumentNullException() 类型的异常时,要为 paramName 参数传递 “value” ,它是属性赋值方法隐含的参数名。

    只读和只写属性

    • 如属性值不变,要创建只读属性。
    • 如属性值不变,从 C# 6.0 起要创建只读自动实现的属性而不是只读属性加支持字段。

    取值和赋值方法的访问修饰符

    • 要为所有属性的取值和赋值方法应用适当的可访问性修饰符。
    • 不要提供只写属性,也不要让赋值方法的可访问性比取值方法更宽松。

    构造函数

    对象初始化器

    • 要为所有属性提供有意义的默认值,确保默认值不会造成安全漏洞或造成代码执行效率大幅降低。自动实现的属性通过构造函数设置默认值。
    • 要允许属性以任意顺序设置,即使这会造成对象短时处于无效状态。

    重载构造函数

    • 如构造函数的参数只是用于设置属性,构造函数参数 (camelCase) 要使用和属性 (PascalCase) 相同的名称,区别仅仅是首字母的大小写。
    • 要为构造函数提供可选参数,并且/或者提供便利的重载构造函数,用好的默认值初始化属性。

    静态成员

    静态构造函数

    • 考虑要么以内联方式初始化静态字段(而不要使用静态构造函数),要么在声明时初始化。

    扩展方法

    • 避免随便定义扩展方法,尤其是不要为自己无所有权的类型定义。

    封装数据

    const

    • 要为永远不变的值使用常量字段。
    • 不要为将来会发生变化的值使用常量字段。

    readonly

    • C# 6.0 开始,要优先选择只读自动实现的属性而不是只读字段。
    • C# 6.0 之前,要为预定义对象实例使用 public static readonly 字段。
    • 如要求版本API兼容性,在 C# 6.0 或更高版本中,避免将 C# 6.0 之前的 public readonly 字段修改成只读自动实现属性。

    嵌套类

    • 避免声明公共嵌套类型。少数高级自定义场景才需考虑。

    接口

    接口概述

    • 接口名称要使用 Pascal 大小写,加 “I” 前缀。

    接口实现

    显式和隐式接口实现的比较

    • 避免显式实现接口成员,除非有很好的理由。但如果不确定,优先显式。

    通过接口实现多继承

    • 考虑定义接口获得和多继承相似的效果。

    版本控制

    • 不要为已交付的接口添加成员。

    比较接口和类

    • 一般优先选择类而不是接口。用抽象类分离契约(类型做什么)与实现细节(类型怎么做)。
    • 如果需要使已从其他类型派生的类型支持接口定义的功能, 考虑 定义接口。

    比较接口和特性

    • 避免使用无成员的标记接口,改为使用特性。

    值类型

    • 不要创建消耗内存大于16字节的值类型

    结构

    • 要创建不可变的值类型。

    初始化结构

    • 要确保结构的默认值有效;总是可以获得结构的默认“全零”值。

    值类型的继承和接口

    • 如需比较相等性,要在值类型上重写相等性操作符 (Equals(),== 和 !=) 并考虑实现 IEquatable<T> 接口。

    装箱

    • 避免可变值类型。

    枚举

    • 考虑使用默认 32 位整型作为枚举基础类型。只有出于互操作性或性能方面的考虑才使用较小的类型,只有创建标志 (flag) 数超过 32 个的标志枚举才使用较大的类型。

    • 考虑在现有枚举中添加新成员,但是要注意兼容性风险。
    • 避免创建代表“不完整”值(如版本号)集合的枚举。
    • 避免在枚举中创建 “保留给将来使用” 的值。
    • 避免包含单个值的枚举。
    • 要为简单枚举提供值 0 来代表无。注意若不显示初始化, 0 就是默认值。

    在枚举和字符串之间转换

    • 如果字符串必须本地化成用户语言,避免枚举/字符串直接转换。

    枚举作为标志使用

    • 要用 FlagsAttribute 标记包含标志的枚举。
    • 要为所有标志枚举提供等于 0None 值。
    • 避免将标志枚举中的零值设定为 “所有标志都未设置” 之外的其他意思。
    • 考虑为常用标志组合提供特殊值。
    • 不要包含 “哨兵” 值(如 Maximum ),这种值会使用户困惑。
    • 要用 2 的乘方确保所有标志组合都不重复。

    小结

    • 不要定义结构,除非它逻辑上代表单个值,消耗 16 字节或更少存储空间,不可变,而且很少装箱。

    合式类型

    重写 object 的成员

    重写 ToString()

    • 如需返回有用的、面向开发人员的诊断字符串,就要重写 ToString()
    • 要使 ToString() 返回的字符串简短。
    • 不要从 ToString() 返回空字符串来代表 “空” (null)
    • 避免 ToString() 引发异常或造成可观察到的副作用(改变对象状态)。
    • 如果返回值与语言文化相关或要求格式化(例如 DateTime ),就要重载 ToString(string format) 或实现 IFormattable
    • 考虑从 ToString() 返回独一无二的字符串以标识对象实例。

    重写 Equals()

    • 要一定 GetHashCode()Equals()== 操作符和 != 操作符,缺一不可。
    • 要用相同算法实现 Equals()==!=
    • 避免在 GetHashCode()Equals()==!= 的实现中引发异常。
    • 避免在可变引用类型上重载相等性操作符(如重载的实现速度过慢,也不要重载)。
    • 要在实现 IComparable 时实现与相等性相关的所有方法。

    操作符重载

    比较操作符(==,!=,<,>,<=,>=)

    • 避免在 == 操作符的重载实现中使用该操作符。

    转换操作符

    转换操作符规范

    • 不要为有损转换提供隐式转换操作符。
    • 不要从隐式转换中引发异常。

    定义命名空间

    • 要为命名空间附加公司名前缀,防止不同公司使用同一个名称。
    • 要为命名空间二级名称使用稳定的、不随版本升级而变化的产品名称。
    • 不要定义没有明确放到一个命名空间中的类型。
    • 考虑创建和命名空间层次结构匹配的文件夹结构。

    XML 注释

    生成 XML 文档文件

    • 如果签名不能完全说明问题,要为公共 API 提供 XML 文档,其中包括成员说明、参数说明和 API 调用示例。

    资源清理

    垃圾回收、终结和 IDisposable

    • 要只为使用了稀缺或昂贵资源的对象实现终结器方法,即使终结会推迟垃圾回收。

    • 要为有终结器的类实现 IDisposable 接口以支持确定性终结。

    • 要为实现了 IDisposable 的类实现终结器方法,以防 Dispose() 没有被显示调用。

    • 要重构终结器方法来调用与 IDisposable 相同的代码,可能就是调用一下 Dispose() 方法。

    • 不要在终结器方法中抛出异常。

    • 要从 Dipose() 中调用 System.GC.SuppressFinalize() ,以使垃圾回收更快地发生,并避免重复性的资源清理。

    • 要保证 Dispose() 可以重入(可被多次调用)

    • 要保持 Dispose() 的简单性,把重点放在终结所要求的资源清理上。

    • 避免为自己拥有的、带终结器的对象调用 Dispose() 。相反,依赖终结队列清理实例。

    • 避免在终结方法中引用未被终结的其他对象。

    • 要在重写 Dispose() 时调用基类的实现。

    • 考虑在调用 Dispose() 后将对象状态设为不可用。对象被 dispose 之后,调用除 Dispose() 之外的方法应引发 ObjectDisposedException 异常。( Dispose() 应该能多次调用。)

    • 要为含有可 dispose 字段(或属性)的类型实现 IDisposable 接口,并 dispose 这些字段所引用的对象。

    异常处理

    多异常类型

    • 要在向成员传递了错误参数时抛出 ArgumentException 或者它的某个子类型。抛出可能具体的异常(例如 ArgumentNullException )。
    • 要在抛出 ArgumentException 或者它的某个子类时设置 ParamName 属性。
    • 要抛出最能说明问题的异常(最具体或者派生得最远的异常)。
    • 不要抛出 NullReferenceException 。相反,在值意外为空时抛出 ArgumentNullException
    • 不要抛出 System.SystemException 或者它的派生类型。
    • 不要抛出 System.Exception 或者 System.ApplicationException
    • 考虑在程序继续执行会变得不安全时调用 System.Environment.FailFast() 来终止进程。
    • 要为传给参数异常类型的 paramName 实参使用 nameof 操作符。接收这种实参的异常包括 ArgumentExceptionArgumentOutOfRangeExceptionArgumentNullException

    异常处理规范

    • 避免在调用栈比较低的位置报告或记录异常。
    • 不该捕捉的异常不要捕捉。要允许异常在调用栈中向上传播,除非能通过程序准确处理栈中较低位置的错误。
    • 如理解特定异常在给定上下文中为何发生,并能通过程序处理错误,就考虑捕捉该异常。
    • 避免捕捉 System.ExceptionSystem.SystemException ,除非是在顶层异常处理程序中先执行最终的清理操作再重新抛出异常。
    • 要在 catch 块中使用 throw ; 而不是 throw <异常对象> 语句。
    • 要先想好异常条件,避免在 catch 块重新抛出异常。
    • 重新抛出不同异常时要当心。
    • 值意外为空时不要抛出 NullReferenceException ,而应抛出 ArgumentNullException
    • 避免在异常条件表达式中抛出异常。
    • 避免以后可能变化的异常条件表达式。

    自定义异常

    • 如果异常不以有别于现有 CLR 异常的方式处理,就不要创建新异常。相反,应抛出现有的框架异常。
    • 要创建新异常类型来描述特别的程序错误。这种错误无法以现有的 CLR 异常来描述,而且需要采取有别于现有 CLR 异常的方式以程序化的方式处理。
    • 要为异常类的名称附加 “Exception” 后缀。
    • 要使异常能由 “运行时” 序列化。
    • 考虑提供异常属性,以便通过程序访问关于异常的额外信息。
    • 避免异常继承层次结构过深。

    重新抛出包装的异常

    • 如果低层抛出的特定异常在高层运行的上下文中没有意义, 考虑 将低层异常包装到更恰当的异常中。
    • 要在包装异常时设置内部异常属性。
    • 要将开发人员作为异常的接收者,尽量说清除问题和解决问题的办法。

    泛型

    泛型类型概述

    类型参数命名规范

    • 要为类型参数选择有意义的名称,并为名称附加 “T” 前缀。
    • 考虑在类型参数的名称中指明约束。

    泛型的接口和结构

    • 避免在类型中实现同一泛型接口的多个构造。

    多个类型参数

    • 要将只是类型参数数量不同的多个泛型类放到同一个文件中。

    嵌套泛型类型

    • 避免在嵌套类型中用同名参数隐藏外层类型的类型参数。

    协变性和逆变性

    数组对不安全协变性的支持

    • 避免不安全的数组协变。相反,考虑将数组转换成只读接口 IEnumerable<T> ,以便通过协变转换来安全地转换。

    委托和 Lambda 表达式

    声明委托类型

    常规用途的委托类型: System.Func 和 System.Action

    • 考虑定义自己的委托类型对于可读性的提升,是否比使用预定义泛型委托类型所带来的便利性来得更重要。

    Lambda 表达式

    语句 Lambda

    • 如类型对于读者显而易见,或者是无关紧要的细节,就考虑在 Lambda 形参列表中省略类型。

    匿名方法

    • 避免在新代码中使用匿名方法语法,优先使用更简洁的 Lambda 表达式语法。

    外部变量

    • 避免在匿名函数中捕捉循环变量。

    事件

    使用多播委托编码 Publish-Subscribe 模式

    检查空值

    • 要在调用委托前检查它的值是不是空值。
    • 要从 C# 6.0 起在调用 Invoke() 前使用空条件操作符。

    理解事件

    编码规范

    • 要在调用委托前验证它的值不为 null 。( C# 6.0 起应使用空条件操作符。)
    • 不要 为非静态事件的 sender 传递 null 值,但要为静态事件的 sender 传递 null 值。
    • 不要eventArgs 传递 null 值。
    • 为事件使用 EventHandler<TEventArgs> 委托类型。
    • 要为 TEventArgs 使用 System.EventArgs 类型或者它的派生类型。
    • 考虑使用 System.EventArgs 的子类作为事件参数类型( TEventArgs ),除非确定事件永远不需要携带任何数据。

    泛型和委托

    • 要为事件处理程序使用 System.EventHandler<T> 而非手动创建新的委托类型,除非必须用自定义类型的参数名加以澄清。

    支持标准查询操作符的集合接口

    标准查询操作符

    使用 Count() 对元素进行计数

    • 要在检查是否有项时使用 System.Linq.Enumerable.Any() 而不是调用 Count() 方法。
    • 要使用集合的 Count 属性(如果有的话),而不是调用 System.Linq.Enumerable.Count() 方法。

    使用 OrderBy() 和 ThenBy 来排序

    • 不要为 OrderBy() 的结果再次调用 OrderBy() 。附加的筛选依据用 ThenBy() 指定。

    使用查询表达式的 LINQ

    查询表达式只是方法调用

    • 要用查询表达式使查询更易读,尤其是涉及复杂的 fromletjoingroup 子句时。
    • 考虑在查询所涉及的操作没有对应的查询表达式时使用标准查询操作符(方法调用),例如 Count()TakeWhile() 或者 Distinct()

    多线程处理

    多线程处理基础

    • 不要以为多线程必然会使代码更快。
    • 要在通过多线程来加快几角处理器受限问题时谨慎衡量性能。

    • 不要无根据地以为普通代码中的原子性操作在多线程代码中也是原子性的,
    • 不要以为所有线程看到的都是一致的共享内存。
    • 要确保同时拥有多个锁的代码总是以相同的顺序获取它们。
    • 避免所有竞态条件条件,程序行为不能受操作系统调度线程的方式的影响。

    使用 System.Threading

    生产代码不要让线程进入睡眠

    • 避免在生产代码中调用 Thread.Sleep()

    生产代码不要中断线程

    • 避免在生产代码中中断 (abort) 线程,因为可能发生不可预测的结果,使程序不稳定。

    线程池处理

    • 要用线程池向处理器受限任务高效地分配处理器时间。
    • 避免将池中的工作者线程分配给 I/O 受限或长时间运行的任务。改为使用 TPL

    异步任务

    用 AggregateException 处理 Task 上的未处理异常

    • 避免程序在任何线程上产生未处理异常。
    • 考虑登记“未处理异常”事件处理程序以进行调试、记录和紧急关闭。
    • 要取消未完成的任务而不是在程序关闭期间允许其运行。

    取消任务

    长时间运行的任务

    • 要告诉任务工厂新建的任务可能长时间运行,使其能恰当地管理它。
    • 要少用 TaskCreationOptions.LongRunning

    线程同步

    线程同步的意义

    为什么要避免锁定this、typeof(type)和string

    • 避免锁定 this、typeof(type) 或字符串
    • 要为同步目标声明 object 类型的一个单独的只读同步变量。

    • 避免用 MethodImplAttribute 同步

    同步设计最佳实践

    • 不要以不同顺序请求相同两个或更多同步目标的排他所有权。
    • 要确保同时持有多个锁的代码总是相同顺序获得这些锁。
    • 要将可变的静态数据封装到具有同步逻辑的公共 API 中。
    • 避免同步对不大于本机(指针大小)整数的值的简单读写操作,这种操作本来就是原子性的。

    平台互操作性与不安全代码

    平台调用

    错误处理

    • 如果非托管方法使用了托管代码的约定,比如结构化异常处理,就要围绕非托管方法创建公共托管包装器。

    设计规范

    • 不要无谓重复现有的、已经能执行的非托管 API 功能的托管类。
    • 要将外部方法声明为私有或内部。
    • 要提供使用了托管约定的公共包装器方法,包括结构化异常处理、为特殊值使用枚举等。
    • 要为非必须参数选择默认值来简化包装器方法。
    • 要用 SetLastErrorAttribute 将使用 SetLastError 错误码的 API 转换成抛出 Win32Exception 的方法。
    • 要扩展 SafeHandle 或实现 IDisposable 并创建终结器来确保非托管资源被高效清理。
    • 要在非托管 API 需要函数指针的时候使用和所需方法的签名匹配的委托类型。
    • 要尽量使用 ref 参数而不是指针类型。
    展开全文
  • 3.IQueryable和IEnumerable几乎完全一样,IQueryable是从IEnumerable派生出来的,但是没有继承IEnumerable的扩展方法,区别:IQueryable实现了Linq Provider这样可以使表达式可以转换成另一种语言,例如C#可以转换成...

    CH15 支持标准查询操作符的集合接口

    15.1集合初始化器

    1.知识点

    1.集合(Collection)类是专门用于数据存储和检索的类I

    2.ICollection<T>和IEnumerable<T>区别:ICollection<T>实现了IEnumerable<T>和 IEnumerable,并且支持Add(),Clear()等操作。

    3.IQueryable<T>和IEnumerable<T>几乎完全一样,IQueryable<T>是从IEnumerable<T>派生出来的,但是没有继承IEnumerable<T>的扩展方法,区别:IQueryable<T>实现了Linq Provider这样可以使表达式可以转换成另一种语言,例如C#可以转换成SQL,只需要通过编写表达式(而不是SQL)就能对完成对数据库的访问。

    4.大多数集合只实现IEnumerable<T>而没有实现ICollection<T>

    15.2 IEnumerable<T>使类成为集合

    1.Foreach与Enumerator关系探究

    现在,我们初始化一个栈

     var stack = new Stack<int>();

    假如我们调用foreach

                    foreach (var item in stack)
                    {
                        Console.WriteLine("任务2输出"+item);
                    }

    foreach这个关键字在单线程任务结果其实这个等价于先获取stack的迭代器,然后调用MoveNext方法,最后记录当前迭代器的current数值。换句话说上面的代码等价于下面代码

             var enumerator = stack.GetEnumerator();
             while (enumerator.MoveNext())
             {
                 number = enumerator.Current;
                 Console.WriteLine("任务2输出"+number);
             }

    那么在多线程的情况下是怎么样的?

            static void Main(string[] args)
            {
                int number;
                var stack = new Stack<int>();
                for (int i = 1; i < 50; i++)
                {
                    stack.Push(i);
                }
    
                Console.WriteLine("第一次测试开始");
                var enumerator = stack.GetEnumerator();
                Task task1 = Task.Run(() =>
                {
                    while (enumerator.MoveNext())
                    {
                        number = enumerator.Current;
                        Console.WriteLine("任务1输出"+number);
                    }
                });
                while (enumerator.MoveNext())
                {
                    number = enumerator.Current;
                    Console.WriteLine("主任务输出"+number);
                }
                task1.Wait();
                Console.WriteLine("第一次测试结束");
                Task task2 = Task.Run(() =>
                {
                    foreach (var item in stack)
                    {
                        Console.WriteLine("任务2输出"+item);
                    }
                });
                foreach (var item in stack)
                {
                    Console.WriteLine("主任务输出"+item);
                }
                task2.Wait();
                Console.WriteLine("第二次测试结束");
    
            }

    第一次输出的结果如下

    可以发现任务1和主任务并不是独立输出的,它们共同输出了一个栈。因为它们共用了一个enumerator,由于线程之间执行情况的不确定性,每个线程会读取当前的迭代器current,导致结果输出的不确定性。

    第二次输出

    第二次输出,虽然两个任务异步进行,但是每个任务都能对应正确输出一个栈。因为每个foreach中都对应一个enumerator,并且在推出循环的时候调用Dispose()方法。

    15.3 标准查询操作符

    1.知识点

    常用查询操作以前写过一次地址:https://lmsniubi.blog.csdn.net/article/details/106453813

    2.Lambda表达式的延迟查询

                    IEnumerable<People> peoples = new List<People>() {new People {UserId="123"}, new People { UserId = "124" }, new People { UserId = "125" }, new People { UserId = "126" } };
                    bool result=false;
                    peoples = peoples.Where(p =>
                    {
                        if (p.UserId == "123")
                        {
                            result = true;
                            Console.WriteLine(p.UserId);
                        }
                        return result;
                    });
                    Console.WriteLine("1.end");
                    foreach (var item in peoples)
                    {
                        
                    }
    
                    Console.WriteLine();
                    Console.WriteLine(peoples.Count());
                    Console.WriteLine("2.end");
    
                    Console.WriteLine();
                    peoples = peoples.ToArray();
                    Console.WriteLine(peoples.Count());
                    Console.WriteLine("3.end");

     输出结果

    输出结果1.end 明明是在 where语句后写的,但是却提前输出,这不符合我们的逻辑顺序。原因是因为Lambda表达式的推迟执行,意思就是Lambda在声明的时候不执行,直到它被使用的那一刻才执行。

    Count()和ToArrary()方法在内部都会使用foreach 触发Lambda表达式的执行,所以输出的结果符合逻辑顺序。

    3.设计规范

    1. 慎用AsParallel(),并行执行代价是可能引入竞态条件,一个线程上的一个操作可能会与一个不同线程上的一个操作混合造成数据被破坏。

    2. 检查集合是否有项目的时候使用Any()方法而不调用Count(),如果集合存在Count属性就不用调用Count()方法

    3. 要避免反复执行,一个查询在执行之后,有必要把获取的数据缓存起来,可以使用Toxxx方法将起赋值给一个缓存的集合,避免无所谓的遍历。

    4. 不要在OrderBy()调用的基础上再调用OrderBy(),而是使用ThenBy(),因为重复调用OrderBy()会撤销上一个OrderBy()的工作。但OrderBy()/OrderByDescending(),ThenBy()/ThenByDescending()升降序方法混用没有问题,但是进一步排序就要使用ThenBy()调用(无论升序还是降序)

    展开全文
  • 书籍推荐:《C#7.0本质论

    千次阅读 2019-08-11 09:23:51
    在dotNet平台中有多种开发语言可以使用,C#无疑是其中应用得最为广泛的。学习一门编程语言最好的方式就是找一本好书系统地学习,我读过的关于C#的书籍中,我认为下面三本最...
  • Essential C# 7.0

    2019-04-19 10:54:53
    Essential C# 7.0 ,C#7.0本质论的英文版,非常清晰的PDF版本,带目录
  • 字符串不可变 所有string类型的数据,不管是不是字符串字面值...C#编译器将C#源代码文件转换成中间语言。 为了将CIL代码转换成处理器能理解的机器码,还要完成一个额外的步骤(通常在运行时进行)。该步骤涉及C#程序..
  • 从今天开始,学习《C# 本质论7.0》这本书,当然作为一个已经了解过面向对象思想和有一定Java和C#编程基础的人,在学习记录的过程中对于简单的前几章学习内容准备采用**QA和记录重点提炼的方式**记录,也就是对于重点...
  • 1. 说明1.1 关于反射、特性在 《C# 7.0 本质论》中,关于这方面的知识在 《第十八章 反射、特性和动态编程》;在《C# 7.0 核心技术指南》中,这部分内容在《第19章 反射和元数据》。[图片来自 《C# 7.0 本质论》]在...
  • C#必读经典三本书

    2019-11-24 16:46:43
    《C#本质论》:入门类,目前最新为《C#7.0本质论》 《C# in Depth》:技巧类,目前最新第四版 《CLR via C#》:底层原理类,目前最新第四版
  • C# 学习书籍推荐(步步为营)

    千次阅读 2020-07-17 13:39:00
    概述 本文只要介绍,C#学习的书籍。 C#入门经典(第8版) C#高级编程(第11版) C#图解教程 第5版(图灵出品) ... C# 7.0本质论[Essential C# 7.0] CLR via C#(第4版) 未完待续。。。 ...
  • C#/.NET书单列表(编程中,官网文档资料很重要) 设计模式可复用面向对象软件的基础 C# 7.0本质论 人月神话 代码大全 C#设计模式
  • 1. 说明1.1 关于反射、特性在 《C# 7.0 本质论》中,关于这方面的知识在 《第十八章 反射、特性和动态编程》;在《C# 7.0 核心技术指南》中,这部分内容在《第19章 反射和...
  • 目录 1,反射的使用概述 2,获取 Type 在上一章中,我们探究了 C# 引入程序集的各种方法,这一章节笔者将探究 C# 中使用反射的...《C# 7.0 本质论》中: 反射是指对程序集中的元数据进行检查的过程。 《C# 7....
  • C#编程规范(一)

    2019-11-26 13:37:46
    所有规范摘抄自书籍《C#7.0本质论》,通过博客分享给大家,希望我们可以在平常的工作学习中常拿来看看,有则改之,无则加勉。 要更注重标识符的清晰而不是简短。 不要在标识符名称中使用单词缩写。 不要使用不被...
  • .NET工程师的书单

    2019-10-04 04:42:12
    短暂的假期里抽空整理了一份书单,以个人的见解这些应该是值得.NET工程师至少去看一遍的书籍。但所罗列的仅包括国内目前已出版的国外书籍的英文版,并不包含中文翻译及相关领域的中文书籍。...C# 7.0本质论,...
  • 引子:时常会有这么一个疑惑,抽象类和接口功能好像,真正用起来该如何抉择呢??好问题。。来看看书上怎么说的(C#7.0本质论)虽然方法可在基类中声明为抽象成员,但是!!如果...
  • 静态方法和实例类

    2020-03-09 10:27:12
    一个类定义好之后,只是定义了一些方式方法和属性的抽象概念,并不能实现直接采用。包括main函数。 如果想作为一个常规编程所使用的函数或子函数...忙了两天,终于理解了《C#7.0本质论》里面12页中间的一段文字。 ...
  • 2020年1月16日学习记录

    2020-01-16 21:13:52
    1.C#7.0本质论—第五章方法和参数内容 2.计算机网络自顶向下—TCP/DUP套接字编程实例简介 3.计算机组成和设计—集成电路简介、性能评估公式(三大要素)、多核处理器编程简介、MIPS概念 4.DMA接口与系统的连接方式...
  • 2020年1月20日学习记录

    2020-01-20 22:36:25
    1.C#7.0本质论第六章、第七章—类的拓展方法、封装数据(const)、嵌套、分部类简介,继承中派生的基本性质。 2.计算机三级数据库技术第三章—数据库逻辑设计概念 3.计算机组成课程第六章—移码、计算机小数表示...
  • 2020年1月18日学习记录

    2020-01-18 21:50:35
    1.C#7.0本质论—第六章类-面向对象编程概念、C#类的声明实例、访问修饰符、属性概念 2.计算机网络自顶向下—第三章运输层第一遍-学习了UDP协议简介(即只提供了端口到端口、纠错检查服务的简单协议)、可靠服务传输...
  • 2020年1月19日学习记录

    2020-01-19 22:23:45
    1.C#7.0本质论第六章类—构造函数、静态成员(static)内容 2.计算机网络自顶向下第三章运输层第一遍—继续学习一个简单的可靠数据传输协议的构造机制,然后开始学习TCP大概。 3.计算机组成与设计第二章计算机语言...
  • 2020年1月17日学习记录

    2020-01-17 22:33:32
    1:C#7.0本质论—参数数组 方法重载 可选参数 异常处理的内容 2.计算机网络自顶向下—第三章运输层第一遍-运输层简介(多路复用和多路分解)和UDP、TCP的工作简介(不同主机不同进程间的通信) 3.计算机组成与设计—...
  • 2020年1月23日学习记录

    2020-01-23 23:02:22
    1.C#7.0本质论 第七章继承—重写基类、抽象类、is操作符内容 2.计算机网络自顶向下第三章运输层—概述及其服务、多路分解与复用(套接字和端口的关系) 3.计算机组成与设计—第二章计算机语言第一遍看完 4.计算机...
  • 来看看书上怎么说的(C#7.0本质论)虽然方法可在基类中声明为抽象成员,但是!!如果都从一个基类派生,会用掉唯一的基类机会,(什么意思呢:也就是C#的单继承特性了),所以,什么都往基类里面加,就会显得特别臃肿,...
  • 2020年1月15日学习记录

    2020-01-15 22:57:39
    1:C#7.0本质论—基本操作符和控制流程、预处理器指令的内容(基本操作符和控制流程有基础,预处理器指令内容为全新) 2:计算机网络自顶向下—第二章应用层中的P2P应用知识(也就是在某某在线网上看盗版视频时候...
  • 突然发现自己的基础不是很牢固,就买了一个《C#7.0本质论》。本系列博客就是以此书为本,记录自己的学习心得,如果你的基础也不牢固,不如跟上博主一起学习成长呀! 本篇博客会从如下几个方面来讲解知识 为什么要...

空空如也

空空如也

1 2
收藏数 30
精华内容 12
关键字:

c#7.0本质论

c# 订阅