【C#8.0 and .NET Core 3.0 高级编程学习笔记】

@C#8.0 and .NET Core 3.0 高级编程学习笔记

前言

为了能精细地完成对C#语言的学习,我决定选择一本书,精读它,理解它,记录它。我想选择什么书并不是最重要的,最重要的是持之以恒的完成这本书的学习实践,并最终转化成自己的能力。
《C#8.0和.NET Core 3.0高级编程》 [英]马克.J.普莱斯 著 王莉莉 译 ,写出来书名主要是为了方便其他看到我这篇文章的读者参照,无任何其他目的。
以此书为蓝本,我预计对1-13进行重点学习。对于 C#的实际应用由于场景太多,我只选择对于我工作学习有用的章节进行学习记录。

目录

  • 第1章 C#与.NET入门
  • 第2章 C#编程基础
  • 第3章 控制程序流程和转换类型
  • 第4章 编写、调试和测试函数
  • 第5章 使用面向对象编程技术构建自己的类型
  • 第6章 实现接口和继承类
  • 第7章 理解和打包.NET类型
  • 第8章 使用常见的.NET类型
  • 第9章 处理文件、流和序列化
  • 第10章 保护数据和应用程序
  • 第11章 使用Entity Framework Core处理数据库
  • 第12章 使用LINQ查询和操作数据库
  • 第13章 使用多任务提高性能和可伸缩性
  • 第14章 C#和.NET的实际应用
  • 第15章 使用ASP.NET Core Razor Pages构建网站
  • 第16章 使用MVC模式构建网站
  • 第17章 使用内容管理系统构建网站
  • 第18章 构建和消费WEB服务
  • 第19章 使用机器学习构建智能应用程序
  • 第20章 构建Windows桌面应用程序
  • 第21章 使用Xamarin.Forms构建跨平台的移动应用程序

第1章 C#与.NET入门

大多数人学习复杂主题的最佳方式是模仿和重复,而不是阅读关于理论的详细解释

1.1 设置开发环境

3种代码编辑器
1、Visual Studio Code
2、Visual Studio 2019
3、Visual Studio 2019 for Mac

1.1.1 使用Visual Studio Code 进行跨平台

     实现跨平台编程(Linux Windows Mac)

1.1.2 使用Visual Studio 2019 进行Windows应用程序开发

创建windows应用程序的唯一编辑器,当然它也可以创建linux应用程序

1.1.3 使用Visual Studio for Mac 进行移动应用程序开发

主要用创建在IOS等苹果操作系统设备上的应用程序

1.1.4 各章的推荐工具

章节 工具 操作系统
第1-19章 Visual Studio Code Windows macOS Linux
第20章 Visual Studio 2019 Windows 10
第21章 Visual Studio 2019 for Mac macOS

1.1.5 跨平台部署

      .NET Core 3.0支持跨平台部署 Linux Windows Mac 

1.1.6 理解Visual Studio Code版本

微软几乎每隔几个月就会发布Visual Studio Code新特性版本以修复版本bug
常见键盘快捷键

动作 macOS Windows
show command palette cmd+shift+p 和F1 Ctrl+Shift+P 和F1
Go to Definition F12 F12

建议根据自己的操作系统下载pdf操作系统快捷键

  • windows 操作系统快捷键PDF下载

1.1.7 下载并安装Visual Studio Code

软件名称 下载链接 说明
visual studio code download 建议使用稳定版本
NET Core SDK download -
C#扩展 - -

1.1.8 其他扩展

扩展 说明
c# for visual studio code 提供c#编辑支持,包括语法高亮,智能感知
c# xml documentation comments 为visual studio code 生成xml文档注释
c# extensions 添加c#类 接口
REST Client 发送HTTP请求并在visual studio code 中直接查看响应

1.2 理解.NET

.NET Framework .NET Core Xamarin 和.NET Standard是相关的,他们是开发人员用来构建应用程序和服务平台

1.2.1 理解.NET Framework

.NET Framework开发平台包括公共语言运行库(CLR)和基础类库(BCL),前者负责管理代码的执行,后者提供了丰富的类库来构建应用程序
实际上,.NET Framework仅适用于windows

1.2.2 理解Mono和Xamarin项目

一些第三方开发了名为Mono项目的.NET Framework实现,Mono是跨平台的。其作为Xamarin移动平台及Unity等跨平台游戏开发平台的基础,找到了自己的应用价值

1.2.3 理解.NET Core

为了解决跨平台问题,微软退出.NET Core平台
2020年11月 .NET Core 简化为.NET

1.2.4 了解.NET的未来版本

.NET Core 不同版本

版本 发布日期
.NET Core 1.0 2016年6月
.NET Core 2.0 2017年8月
.NET Core 3.0 2019年9月
.NET 5.0 2020年11月
.NET 6.0 2021年11月

1.2.5 了解.NET支持

LTS版本是稳定的,在其生命周期中少有更新

1.2.6 .NET Core有什么不同

相比.NET Framework 的当前版本要小,是因为旧技术已经被移除;
微软的目的不是让.NET Core 变小,而是将其组建化,部署时按需选择即可

1.2.7 了解.NET Standard

微软定义了所有.NET平台都必须实现的API规范 .NET Standard;
理解.NET Standard只是一种标准很重要,.NET Standard版本以及支持这些版本的.NET平台download

1.2.8 本书使用的.NET平台和工具

visual studio code

1.2.9 理解中间语言

dotnet CLI工具使用的C#编译器(Roslyn)会将C#源代码转换成中间语言(Intermediate Language,IL)代码,并将IL存储在程序集(DLL或exe文件)中,IL代码语句就像汇编语言指令,由.NET Core的虚拟机CoreCLR执行

1.2.10 了解.NET Native

.NET Native用于将C#代码提前(Ahead of Time ,AoT)编译成本机CPU指令,而不是用CLR编程成IL代码。故执行速度快,占用内存低

1.2.11 比较.NET技术

.NET技术 说明 驻留的操作系统
.NET Core 现代功能集 完全支持C#8.0 跨平台
.NET Framework 旧的特性集 windows
Xamarin 移动及桌面应用 Android ios macos
微软承诺将来只有一个.NET平台而不是3个

1.3 使用Visual Studio Code 构建控制台应用程序

1.3.1 使用Visual Studio Code 编写代码

  1. 在电脑保存程序地方新建程序名文件夹test
  2. 点击 file->openfolder
  3. 在vscode编码区下方 terminal处 使用命令 dotnet new console
  4. 稍微修改代码 program.cs
  5. 运行控制台应用程序 dotnet run
  6. 查看运行结果
    【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第1张图片

1.3.2 使用dotnet CLI编译和运行代码

1.4 从GitHub存储库下载解决方案代码

1.4.1 使用Git和Visual Studio Code

github上pull push 代码速度很慢,推荐使用gittee代替(码云)

1.4.2 拷贝图书解决方案代码存储库

1.5 寻求帮助

1.5.1 阅读微软文档

权威资源download

1.5.2 获取关于dotnet工具的帮助

dotnet help new

1.5.3 获取类型和成员的定义

Go to Definition (快捷键F12)

1.5.4 在Stack Overflow上寻找答案

Stack Overflow 是最受欢迎的第三方网站。 虽然作者这么说,但是国内访问速度比较慢

1.5.5 使用谷歌搜索答案

使用goggle浏览器搜索答案比较准确

1.5.6 订阅官方的.NET博客

.NET 官方博客地址

1.6 实践与探索

1.6.1 练习1.1:测试你掌握的知识

1.6.2 练习1.2:在任何地方练习C#

1.6.3 练习1.3:探索主题

1.7 本章小结

第2章 C#编程基础

2.1 介绍C#

2.1.1 理解语言版本和特性

1.0==》8.0特性简介

版本 特性说明
1.0 2002年发布,包含静态类型的面向对象编程语言
2.0 2005年发布,泛型实现强数据类型,以提高代码性能,减少类型错误
3.0 2007年发布,集成查询LINQ,匿名类型,lambda表达式等
4.0 2010年发布,F#,Python等动态语言改进互操作性
5.0 2012年发布,简化异步操作支持
6.0 2015年发布,细微改进
7.0 2017年发布,添加功能语言特性
7.1 2017年8月发布,对语言细微改进
7.2 2017年12月发布,对语言细微改进
7.3 2018年发布,关注性能导向型安全代码,改进了ref变量,指针,stackalloc
8.0 2019年发布,关注空处理处理

2.1.2 发现C#编译器版本

C#7.x中,微软加快了语言发布节奏–发布次要版本号,也称为点发布
.NET语言编译器 作为.NET Core SDK的一部分发布
在vscode中查看由哪些可以使用的版本
dotnet --version

2.1.3 启用特定的语言版本编译器

在项目文件中添加配置元素
8.1

2.2 了解C#基本知识

2.2.1 了解C#语法

*注释永远不应该是记录代码的唯一方式,为变量和函数选择合理的名称,编写单元测试和创建文字文档是记录代码的其他方法

  1. 语句 使用分号表示语句结束,可以由多个变量和表达式组成
  2. 注释 使用双斜杠添加注释解释代码,注释文字部分不执行
  3. 块 {}表示,可以定义名称空间,类,方法,语句

2.2.2 了解C#词汇表

C#词汇表是由关键字,符号字符和类型组成
大约100个关键字 using namespace class…

  1. 如何编写正确的代码
    使用VS CODE 等编程软件去帮助自己完成代码的检查,提高编程效率
  2. 动词表示方法
    在C#中,动作和行动被称之为方法。
  3. 名词表示类型,字段,和变量
    区别type(类型) 和class(类)
    在C#中,每种类型都可以归类为类,结构,枚举,接口,委托。所以类型的定义更为宽泛
  4. C#词汇表的范围
    100个关键字,
    一段代码看看C#程序中用到的方法和类型
 //loop through the assamblies that this app reference
            foreach (var r in Assembly.GetEntryAssembly().GetReferencedAssemblies())
            {
                //load the assembly so we can read its details
                var a=Assembly.Load(new AssemblyName(r.FullName));

                //declare a variable to count the number of methods
                int methodCount=0;
                //loop through all the types in the assembly
                foreach (var t in a.DefinedTypes)
                {
                    // add up the counts of methods
                    methodCount+=t.GetMethods().Count();
                }

                // output the count of types and their methods
                System.Console.WriteLine(
                    "{0:N0} types with {1:N0} methods in {2} assembly .",
                arg0:a.DefinedTypes.Count(),
                arg1:methodCount,
                arg2:r.Name);
                
            }

输出结果 C#语言中有大量的类型和方法
在这里插入图片描述

使用变量

当使用变量时,首先考虑它可能在内存中的占用的空间,然后考虑处理速度

2.3.1命名和赋值

命名约定 示例 使用场合
驼峰样式 Cost orderDetail dateofBirth 局部变量 私有字段
标题样式 String Int32 Cost DateOfBirth Run 类型 非私有字段以及其他成员(如方法)
遵循一组一致的命名约定,可以使代码更容易被自己或者其他开发人员理解(更重要的是未来的自己)
字面值

表示固定值的符号

2.3.2 存储文本

char a='a';
char b='1';
string name="yong";
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(name);

string fullname="Tim\tSun";
Console.WriteLine(fullname);

//理解逐字字符串
string fileRoute=@"C:\test\sony\123.txt"
Console.WriteLine(fileRoute);

输出结果
在这里插入图片描述

2.3.3 存储数字

  1. 存储整数
    C#7.0及最高版本使用下划线作为数字分割符
int count1=1_0000_0000;
int count2=1;
int count3=count1+count2;
Console.WriteLine(count3.ToString());

【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第2张图片
2. 存储实数
计算机并不能总是精确地表示浮点数 float和double类使用单精度和双精度浮点数存储实数
IEEE754是电气和电子工程师协会(IEEE)于1985年建立的浮点运算技术标准
3. 编写代码探索数字的大小
使用sizeof() MinValue MaxValue 观察类型占用空间的大小和最小最大值

            //观察各种数字类型占用的空间及最大最小值
           Console.WriteLine($"int uses {sizeof(int)} bytes and can store numbers in the range {int.MinValue:N0} to {int.MaxValue:N0}");
           Console.WriteLine($"int uses {sizeof(float)} bytes and can store numbers in the range {float.MinValue:N0} to {float.MaxValue:N0}");
           Console.WriteLine($"int uses {sizeof(double)} bytes and can store numbers in the range {double.MinValue:N0} to {double.MaxValue:N0}");

输出结果
在这里插入图片描述
4. 比较double和decimal类型
double类型不能保证值是准确的,因为有些数字不能表示为浮点值。

//CP02--比较double和decimal

double a=0.1;
double b=0.2;
double c=a+b;
if (c==0.3)
{
     System.Console.WriteLine($"{a}+{b} equals 0.3 ");                
}
else
{
     System.Console.WriteLine($"{a}+{b} does not equals 0.3 ");
     System.Console.WriteLine($"{a}+{b} equals {c}");
} 

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第3张图片
永远不用用==比较2个double值。在第一次海湾战争,美国爱国者导弹系统计算时使用double值,这种不准确性导致其无法跟踪拦截伊拉克飞毛腿导弹

解决办法

System.Console.WriteLine("use decimal type to solute !!");
decimal d=0.1M;//M suffix means a decimal literal value
decimal e=0.2M;
decimal f=d+e;
if (f==0.3M)
{
    System.Console.WriteLine($"{d}+{e} equals 0.3 ");                
}
else
{
     System.Console.WriteLine($"{d}+{e} does not equals 0.3 ");
     System.Console.WriteLine($"{d}+{e} equals {f}");
}

输出结果(注意double和decimal类型无法直接==运算)
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第4张图片
decimal类型是准确的,常用于货币,CAD绘图,一般工程学以及任何对实数的准确性要求较高的场合

2.3.4 存储布尔值

true false

2.3.5 使用vs code 工作区

在使用工作区时,在终端输入命令一定要小心,保证当前处于你想要的文件路径中
@不知道为什么作者在这个部分说明这个问题?可能他在这里入过坑

2.3.6 存储任何类型的对象

object 可以存储任何数据,代价是代码混乱,性能较差
C#1.0版本就有了object类型,但是在C#2.0以后有更好的选择泛型。泛型可以提供想要的灵活性,且没有性能开销。见第6章

2.3.7 动态存储类型

dynamic 可用于存储任何类型的数据,灵活性比object更强。代价是性能降低了
并且他可以在没有显示强制转换的情况下调用成员

//dynamic 类型
dynamic anothername="tom";
int length=anothername.Length;
System.Console.WriteLine($"its length is {length}");

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第5张图片

2.3.8 声明局部变量

制定或推断变量类型

//声明变量 指定或推断变量的类型
System.Console.WriteLine("declear or just use keyword var");

var count=3;  //clearly enough
var height=1.2;
var price=4.9M;

var file1=File.CreateText(@"something1.txt");          //must take some time to think
StreamWriter file2=File.CreateText(@"something2.txt");  //more clearly

2.3.9 获取类型的默认值

除了string之外,其他基本类型都是值类型,意味着他们必须有值。可以使用default()操作确认
而string是引用类型,可以有空值

System.Console.WriteLine("");
// 获取类型默认值
System.Console.WriteLine("获取类型的默认值");
System.Console.WriteLine($"default(int) is {default(int)}");
System.Console.WriteLine($"default(bool) is {default(bool)}");
System.Console.WriteLine($"default(DateTime) is {default(DateTime)}");
System.Console.WriteLine($"default(string) is {default(string)}");

2.3.10 存储多个值

需要存储同一类型的多个值,可以用数组

System.Console.WriteLine("认识数组");
string[] names=new string[3];
names[0]="tim";
names[1]="tom";
for (int i = 0; i < 3; i++)
{
     System.Console.WriteLine($"name is {names[i]}");
}

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第6张图片

2.4 处理空值

2.4.1 使值类型为null

默认情况下,想int DateTime这样的类型都有值,但有时,当读取存储在数据库中允许的空值或缺失值时,允许空值非常方便

System.Console.WriteLine("");//隔行
// 定义可空变量
System.Console.WriteLine("定义可空变量");
int? thiscanbenull=4;
thiscanbenull=null;
System.Console.WriteLine($"thiscanbenull is {thiscanbenull}");

结果输出
在这里插入图片描述

2.4.2 启用可空引用类型和不可空引用类型

  1. 项目级别 在项目文件中更改
<propertyGroup>
<Nullable>enable</Nullalbe>
</propertyGroup>
  1. 文件级别 需要可空的代码段
#nullable disable
#nullable enable

2.4.3 声明不可为空的变量和参数

【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第7张图片

2.4.4 检查null

必须在使用可空变量之前检查空值
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第8张图片

2.5 深入研究控制台应用程序

2.5.1 向用户显示输出

  1. 使用编号的位置参数进行格式化
//使用编号的位置参数进行格式化
System.Console.WriteLine("使用编号的位置参数进行格式化");
int number=10;
decimal price11=1.2M;
System.Console.WriteLine(
      format:"{0} apples costs {1:c}",
      arg0:number,
      arg1:number*price11);

输出
在这里插入图片描述
2. 使用内插字符串进行格式化

int a=10;
System.Console.WriteLine($"{a} is 10")

2.5.2 理解格式字符串

N0格式表示有千位分隔符且没有小数点的数字 C格式表示货币 {arg,N} N=-8 左对齐8个字符长度列 {arg,N} N=6 右对齐6个字符长度列

//格式字符串例子
System.Console.WriteLine("格式字符串例子");
System.Console.WriteLine(
     format:"{0,-8} {1,6:N0}",
     arg0:"name",
     arg1:"count");

System.Console.WriteLine(
    format:"{0,-8} {1,6:N0}",
    arg0:"apple",
    arg1:123456);

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第9张图片

2.5.3 从用户那里获取文本信息

System.Console.WriteLine("----获取用户文本输入-----");
System.Console.WriteLine("type your name and press enter ");
string name123=System.Console.ReadLine();
System.Console.WriteLine("type your age and press enter ");
string age=System.Console.ReadLine();
System.Console.WriteLine($"so your name is {name123} and your age is {age}");

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第10张图片

2.5.4 导入名称空间

using System
导入名称空间的效果是,名称空间的所有可用类型都对程序可用,不需要输入空间名称前缀

2.5.5 简化控制台的使用

2.5.6 获取用户的重要输入

System.Console.WriteLine("----获取用户的重要输入-----");
System.Console.WriteLine("press any key combination");
ConsoleKeyInfo key=ReadKey();
WriteLine();
System.Console.WriteLine(
     format:"key:{0},Char:{1},Modifiers:{2}",
     arg0:key.Key,
     arg1:key.KeyChar,
     arg2:key.Modifiers);

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第11张图片

2.5.7 获取参数

Main方法中的string[] args是用于向控制台应用程序传递参数数组
命令行参数由空格分隔

System.Console.WriteLine("");
//获取参数
System.Console.WriteLine("---获取参数---");
System.Console.WriteLine($"main input args {args[0]}");

结果输出 dotnet run a
在这里插入图片描述

2.5.8 使用参数设置选项

可以设置控制台的背景颜色,尺寸等参数

2.5.9 处理不支持API 的平台

try catch

2.6 实践和探索

探索主题

主题 链接
C#关键字 资料下载

第3章 控制程序流程和转换类型

3.1 操作变量

3.1.1 一元运算符

++ –

//一元操作符
System.Console.WriteLine("----一元操作符----");
int a=3;
int b=a++;
System.Console.WriteLine($"b is {b}, a is {a}");

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第12张图片

3.1.2 二元运算符

3.1.3 赋值运算符

3.1.4 逻辑运算符

//逻辑运算符
System.Console.WriteLine("");
System.Console.WriteLine("---逻辑运算符---");
bool h = true;
bool i = false;
System.Console.WriteLine(
                format: "{0,-8}\t{1,-8}\t{2,-8}",
                arg0: "AND",
                arg1: "h",
                arg2: "i");
System.Console.WriteLine(
                format: "{0,-8}\t{1,-8}\t{2,-8}",
                arg0: "h",
                arg1: $"{h & h}",
                arg2: $"{h & i}");
System.Console.WriteLine(
                format: "{0,-8}\t{1,-8}\t{2,-8}",
                arg0: "i",
                arg1: $"{i & h}",
                arg2: $"{i & i}");     

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第13张图片
其余 OR或运算 | XOR逻辑运算符^

3.1.5 条件逻辑运算符

也称短路布尔运算符

//条件逻辑运算符
System.Console.WriteLine("");
System.Console.WriteLine("---条件逻辑运算符---");  
System.Console.WriteLine($"h & DoStuff() = {h & DoStuff()}");
System.Console.WriteLine($"i & DoStuff() = {i & DoStuff()} ");
System.Console.WriteLine("---------");
System.Console.WriteLine($"h && DoStuff() = {h && DoStuff()}");
System.Console.WriteLine($"i && DoStuff() = {i && DoStuff()} ");

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第14张图片

从示例中可以看出为什么条件逻辑运算符被描述未短路布尔运算符,它们可以使得应用程序更高效。但是会在假定函数总是被调用的情况下引入一些细微bug

3.1.6 按位和二元移位运算符

二元移位运算符相比传统的运算符执行更快,因为它操作的是数字的位
位运算

//按位运算
System.Console.WriteLine("");
System.Console.WriteLine("按位运算");
int j=10;//0000 1010
int k=6; //0000 0110
System.Console.WriteLine($"j & k ={j&k}");
System.Console.WriteLine($"j | k ={j|k}");
System.Console.WriteLine($"j ^ k ={j^k}");

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第15张图片
移位运算

//移位运算
System.Console.WriteLine("");
System.Console.WriteLine("移位运算");
System.Console.WriteLine($"j<<3 = {j<<3}");
System.Console.WriteLine($"k>>1 = {k>>1}");

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第16张图片

3.1.7 其他运算符

nameof 以字符串值的形式返回变量
sizeof 返回简单类型的字节大小

 //nameof sizeof
System.Console.WriteLine("");
System.Console.WriteLine("---nameof sizeof ---");
int age=1000;
System.Console.WriteLine($"var age,s name is {nameof(age)}");
新的写法  避免了age变量名更改后,忘记更改字符串"age",因为字符串编译器是不错提示错误的
System.Console.WriteLine($"var int,s size is {sizeof(int)}");

输出结果
【C#8.0 and .NET Core 3.0 高级编程学习笔记】_第17张图片

3.2 理解选择语句

你可能感兴趣的:(学习笔记,c#)