详细请看官方文档
https://gitee.com/zhontai/Admin.Core
https://github.com/shuxinqin/Chloe //轻量orm库
https://www.cnblogs.com/huguodong/p/12896604.html //web api系列教程
https://github.com/Deali-Axy/AspNetCore-Learning-Mvc
https://gitee.com/dotnetchina //dotNET China(gitee 项目)
https://www.cnblogs.com/landeanfen/p/4976838.html //bootstrap table系列使用
https://github.com/abpframework/abp-samples //ABP Framework Sample Projects
https://github.com/yangzhongke //杨中科
https://gitee.com/x_discoverer/projects //xm
https://github.com/1397771033/MyBlog
dotnet --version //查看版本
dotnet new console//当前文件夹下创建控制台项目
dotnet --list-sdks//查看已安装的sdk
dotnet new webapi -f net6.0//创建一个Web API 项目
dotnet run //构建并运行
// NuGet
Install-Package XXX。-Version//指定版本。
Uninstall-Package XXX//卸载
Update-Package XXX//更新到最新版
CTRL+K+C//1.注释
CTRL+K+U//2.取消注释
CTRL+M+O//1.展开
CTRL+M+L//2.合并
Ctrl+M,M//快速隐藏或显示当前代码段
CTRL+L//删除该行
CTRL+Enter//在光标所在行的上面插入一行
CTRL+Shift+Enter//在光标所在行的下面插入一行
CTRL+F//查找.替换
Shift+Alt+方向键(或鼠标)//代码行和列进行选择,对批量删除某些代码
Ctrl+J//智能提示
Ctrl+Tab//快速切换窗口
c+k+k//书签
c+k+p
c+k+n
Ctrl+Shift+B//生成解决方案
SHIFT + ALT + ENTER//全屏显示/退出全屏显示
Alt+向上键 // 上移行
Alt+向下键 // 下移行
.NET 是NET Framework、.NET Core、Xamarin/Mono的统称。
1、系统级别的安装,互相影响
2、无法独立部署
3、ASP.NET 和IIS深度耦合
4、ASP.NET资源消耗大
5、非云原生
.NET Framework历史包袱:
1、带着手铐脚镣长大的ASP.NET MVC
2、ASP.NET底层不支持很好的单元测试
1)支持独立部署,不互相影响;
2)彻底模块化;
3)没有历史包袱,运行效率高
4)不依赖于IIS
5)跨平台
6)符合现代开发理念:依赖注入、单元测试等
1.NET Standard只是规范,一个.NET Standard类库可以被支持其版本的.NET Framework、.NET Core,Xamarin等引用。而.NET Core库、.NET Framework类库则不可以。
2.如果编写一个公用的类库,尽量选择.NET Standard,并且尽量用低版本。
1) .NET CLI: 命令行
2) Visual Studio: Windows-Only (推荐)
3) Visual Studio for Mac
4) Jetbrains Rider:(挺好用的,不骗人)
5) VS Code (Visual Studio Code): 跨平台
1.从.NET 5开始,微软开始淡化其他叫法,统一为.NET,后续默认.NET就是指的.NET Core。
2.文档中英文切换。也许可以手动改 zh-cn/en-us
3.自学就要养成把相关文档“翻一翻”的意识。
包管理
Linux:apt、yum
Javascript:npm
Java:Maven、Gradle
Python:pip
.net:NuGet
使用 Async 和 Await 的异步编程
异步方法”:用async关键字修饰的方法
1 .异步方法的返回值一般是Task,T是真正的返回值类型,Task。惯例:异步方法名字以Async结尾。
2. 即使方法没有返回值,也最好把返回值声明为非泛型的Task。
3.调用泛型方法时,一般在方法前加上await关,这样拿到的返回值就是泛型指定的T类型;
4.异步方法的“传染性”:一个方法中如果有await调用,则这个方法也必须修饰为async
async方法缺点:
1、异步方法会生成一个类,运行效率没有普通方法高;
2、可能会占用非常多的线程;
…
如果想在异步方法中暂停一段时间,不要用Thread.Sleep(),因为它会阻塞调用线程,而要用await Task.Delay()。举例:下载一个网址,3秒后下载另一个。
异步与yield:
复习: yield return不仅能够简化数据的返回,而且可以让数据处理“流水线化”,提升性能
static async Task<int> DownloadAsync(string url, string destFilePath)
{
string body;
using (HttpClient httpClient = new HttpClient())
{
body = await httpClient.GetStringAsync(url);
}
await File.WriteAllTextAsync(destFilePath, body);
return body.Length;
}
控制反转两种实现方式:
- 服务定位器(ServiceLocator);
- 依赖注入(Dependency Injection,DI)
DI几个概念
服务(service):对象;注册服务;
服务容器:负责管理注册的服务;
查询服务:创建对象及关联对象;
对象生命周期:Transient(瞬态); Scoped(范围); Singleton(单例);
为什么要学LINQ?让数据处理变得简单
LINQ中提供了大量类似Where的扩展方法,简化数据处理。
委托→lambda→LINQ
LINQ中所有的扩展方法几乎都是针对IEnumerable接口的,而几乎所有能返回集合的都返回IEnumerable,所以是可以把几乎所有方法“链式使用”的。
学习参考1
学习参考2
(复习)委托
1、委托是可以指向方法的类型,调用委托变量时执行的就是变量指向的方法。举例。
2、.NET 中定义了泛型委托Action(无返回值)和Func(有返回值),所以一般不用自定义委托类型。
//统计一个字符串中每个字母出现的频率(忽略大小写),然后按照从高到低的顺序输出出现频率高于2次的单词和其出现的频率。
var items = s.Where(c => char.IsLetter(c))//过滤非字母
.Select(c => char.ToLower(c))//大写字母转换为小写
.GroupBy(c => c)//根据字母进行分组
.Where(g=>g.Count()>2)//过滤掉出现次数<=2
.OrderByDescending(g => g.Count())//按次数倒序排序
.Select(g=>new { Char=g.Key,Count=g.Count()});
//委托变量不仅可以指向普通方法,还可以指向匿名方法
Func<int, int, string> f1 = delegate (int i1, int i2) {
return $"{i1}+{i2}={i1 + i2}";
};
string s = f1(1, 2);
//匿名方法可以写成lambda表达式
Func<int, int, string> f1 = (i1,i2) =>{
return $"{i1}+{i2}={i1 + i2}";
};
Func<int, int, string> f1 = (i1, i2) => $"{i1}+{i2}={i1 + i2}";
//如果委托没有返回值,且方法体只有一行代码,可省略 {}
Action<int, string> a1 = (age, name) => Console.WriteLine($"年龄{age},姓名{name}");
a1(18, "yzk");
//如果只有一个参数,参数的()可以省略。
Action<string> f1 = s => Console.WriteLine(s);
//==================================
//var让编译器的“类型推断,是强类型,弱类型是dynamic
using System.Linq;
int[] nums = new int[]
{ 3,99,88,77,7,8,9,66,15,7};
IEnumerable<int> items = nums.Where(i=>i>10);
Count()//方法:获取数据条数
int count2 = list.Where(e => e.Salary > 5000 || e.Age < 30).Count();
Any()//方法:是否至少有一条数据
bool b2 = list.Where(e => e.Salary > 8000).Any();
Max()、Min () 、Average () 、Sum () 、Count ()//聚合函数
ist.Where(e => e.Age > 30).Min(e=>e.Salary)
GroupBy()//分组条件
//投影:把集合中的每一项转换为另外一种类型。
IEnumerable<string> names = list.Select(e=>e.Gender?"男":"女");
var dogs = list.Select(p=>new Dog{NickName=e.Name,Age=e.Age});
//集合转换:我们可以用ToArray()方法和ToList()分别把IEnumerable转换为数组类型和List类型。
//使用Where、OrderBy、Select等 扩展方法进行数据查询的写法叫做 “LINQ方法语法”。还有一种“查询语法”的写法。
var items2 = from e in list
where e.Salary > 3000
orderby e.Age
select new { e.Name, e.Age, Gender = e.Gender ? "男" : "女" };
1、表达式树(Expression Tree):树形数据结构表示代码,以表示逻辑运算,以便可以在运行时访问逻辑运算的结构。
2、Expression<TDelegate>类型
3、从Lambda表达式来生成表达式树:
Expression<Func<Book, bool>> e1 = b =>b.Price > 5;
//Expression和委托的关系和区别
1、把Expression<Func<Book, bool>>换成Func<Book, bool>,写成下面的版本:
Func<Book, bool> e = b => b.Price > 5;
ctx.Books.Where(e).ToList();
2、Expression对象储存了运算逻辑,它把运算逻辑保存成抽象语法树(AST),可以在运行时动态获取运算逻辑。而普通委托则没有。
//通过代码查看AST
1、Install-Package ExpressionTreeToString
2、Expression<Func<Book, bool>> e = b => b.AuthorName.Contains("杨中科")||b.Price>30;
Console.WriteLine(e.ToString("Object notation", "C#"));
//C#命名规范
Camel命名法(驼峰命名法)
首个单词的首字母小写,其余单词的首字母大写(enemyHp)
Pascal命名规范
每个单词的第一个字母都大写(EnemyHp)
如果使用到英文单词的缩写,全部使用大写(PI HP MP)
变量使用Camel命名,方法和类使用Pascal命名规范
变量的声明
int age ;
变量的赋值
age = 25;
变量的声明和赋值可以放在一个语句中
int age = 25;
变量在使用之前必须初始化
第一次给变量赋值,就叫做初始化
//委托的使用
elegate double MyDelegate(double param1,double param2);
static double Multiply(double param1,double param2){
return param1*param2;
}
static double Divide(double param1,double param2){
return param1/param2;
}
double param1 = 34; double param2 =2;
MyDelegate de;
de = Multiply;
de(param1,param2);
de = Divide;
de(param1,param2);
//堆和栈 : 程序运行时的内存区域
我们把内存分为堆 空间和栈空间
栈空间比较小,但是读取速度快
堆空间比较大,但是读取速度慢
栈的特征:
数据只能从栈的顶端插入和删除
把数据放入栈顶称为入栈(push)
从栈顶删除数据称为出栈(pop)
堆是一块内存区域,与栈不同,堆里的内存能够以任意顺序存入和移除
//关于字符串的更多方法(string)
1,CompareTo()方法,比较字符串的内容
2,Replace()用另一个字符或者字符串替换字符串中给定的字符或者字符串
3,Split()在出现给定字符的地方,把字符串拆分称一个字符串数组
4,SubString()在字符串中检索给定位置的子字符串
5,ToLower()把字符串转换成小写形式
6,ToUpper()把字符串转换成大写形式
7,Trim()删除首尾的空白
8,Concat()方法,合并字符串
9,CopyTo()方法,把字符串中指定的字符复制到一个数组中
10,Format()方法,格式化字符串
11,IndexOf()方法,取得字符串第一次出现某个给定字符串或者字符的位置
12,IndexOfAny()方法,
13,Insert()把一个字符串实例插入到另一个字符串实例的制定索引处
14,Join()合并字符串数组,创建一个新字符串
//stringbuilder
1,创建StringBuilder对象
StringBuilder sb = new StringBuilder("www.taikr.com");
StringBuilder sb = new StringBuilder(20);
StringBuilder sb = new StringBuilder("www.devsiki.com",100);
关于StringBuilder对象创建的时候的内存占用
2,Append()方法,给当前字符串追加一个字符
3,Insert()追加特定格式的字符串
4,Remove()从当前字符串中删除字符
5,Replace()在当前字符串中,用某个字符或者字符串全部替换另一个字符或者字符串
6,ToString()把当前stringBuilder中存储的字符串,提取成一个不可变的字符串
定位元字符 正则表达式
string str = "I am Blue cat";
Console.WriteLine(Regex.Replace(str, "^", "准备开始:"));//区配开始 ^
Console.WriteLine(Regex.Replace(str, "$", " 结束了!"));//区始结束 $
有待更新