.net
Linq
委托->lambda->LINQ
int i=5;
整数类型的变量i指向数据5;
委托是可以指向方法的类型。
调用委托变量时执行的就是变量指向的方法。
.net中定义了泛型委托Action(无返回值)和Func(有返回值),所以一般不用自定义委托类型。
static void f1(int z,int c){
}
//main函数
int main(){
Action<int,int> f=f1
}
委托变量不仅可以指向普通方法,也可以指向匿名方法。
//delegate开头的为匿名方法的声明
Func<int ,int,string> f1=delegate(int i1,int i2)
{
return $"{i1}+{i2}={i1+i2}";
};
string s=f1(1,2);
将匿名方法改成lamdba
Func<int ,int,string>=(int i1,int i2)=>{return $"{i1}+{i2}={i1+i2}";};
string s=f1(1,2);
如果 =>之后的方法体中只用一行代码,且方法有返回值,那么可以省略方法体的{}以及return.
Func<int ,int,string> f1=(i1,i2)=>$"{i1}+{i2}={i1+i2}";
LINQ的where方法
int[] nums=new int[]{3,5,6,87,89,45,7,435,45,765,324};
IEnumerable<int> result=num.Where(a=>a>10);
foreach(int i in result)
{
Console.WriteLine(i);
}
where方法会遍历集合中的每个元素,对每个元素都调用lamdba表达式,判断是否为true.
LINQ常用方法
这些方法中大多都是对基于IENumeable的扩展方法。
//返回符合条件的元素
IEnmerable<int> items=list.where(p=>p.Age>30);
//返回符合条件的元素个数
int item=list.Count(p=>p.Age>30);
//判断是否至少有一条数据符合要求
bool item=list.Any(p=>p.Age>30);
只取其中一条数据
//有且只有一条满足要求的数据,返回数据
Single()
//最多只有一条满足要求的数据,返回数据
SingleOrDefault()
//至少有一条,返回第一条,返回数据
First()
//返回第一条或默认值,返回数据
FirstOrDefault()
排序
//排序
//对数据进行正向排序
//没有无参的构造函数,至少写成OrderBy(i=>i);适用于简单类型
//随机排序OrderBy(e=>Guid.NewGuid());
//支持多条件排序,OrderBy(...).ThenBy(...);
OrderBy()
list.OrderBy(e=>e.Age);
//倒序排序
OrderByDescending()
对于简单类型排序,也许不用lambda表达式。
特殊案例:按照最后一个字符排序;用Guid或者随机书进行随机排序。
跳过
//跳过某些数据,取部分数据
Skip();
Take();
list.Skip(3).Take(2);//跳过二条数据,取第三条数据
聚合函数
Max()//最大值
Min()//最小值
Average()//平均值
Sum()//和
Count()//个数
只要是可以返回IEnmerable的,都可以使用链式调用
分组
IEnumerable<IGrouping<int,Employee>> items=list.GroupBy(e=>e.Age);
映射
把集合中的每一项逐个转换成另一类型
IEnumable<int> age=list.Seleect(e=>e.age);
匿名类型
var obj1=new {Name="ddd",Salary=3,AAA="eadwr",BB=99};
//编译器,定义四个属性,并创建了一个对象
匿名类型和投影结合
var items=list.Select(e=>new {XingMing=e.Name,NianLing=e.Age,XingBie=e.Gender?"男":"女"});
集合转换
我们可以利用ToArray()方法和ToList()分别把IEnumerable转换为数组类型和List类型。
依赖注入
依赖注入是实现控制反转的一种方式
不要在长生命周期的对象内引用短生命周期的对象。
生命周期的选择:
如果类无状态,建议为Singleton;如果类有状态,且有Scope控制,建议为Scoped。使用
瞬态的时候要谨慎。
系统配置
Json文件配置
{
"name":"yzk",
"age":"18",
"proxy":{"address":"aa"}
}
NuGet安装Microsoft.Extensions.Configuration和Mincrosoft.Extensions.Configuration.Json
读取配置原始方法
ConfigurationBuilder configBuilder=new ConfigurationBuilder();
configBuilder.AddJsonFile("config.json",optional:false;reloadOnChange:true);
IConfigurationRoot config=configBuilder.Build();
string name=config["name"];
string proxyAddress=config.GetSection("proxy:address").Value;
optional参数表示这个文件是否可选,设为false文件不存在会报错。
reloadOnChange(可选):一个布尔值,指示是否在文件更改时重新加载配置。如果设置为 true,则当文件更改时,配置将自动重新加载
绑定读取配置
NuGet安装:Microsoft.Extensions.Configuration.Binder
Proxy proxy=configRoot.GetSection("proxy").Get<Proxy>();
把配置文件直接映射为对象也可以
class Config
{
pubilc string Name{get;set;}
pubilc int Age{get;set;}
pubilc Proxy proxy{get;set;}
}
class Proxy
{
pubilc string Address{get;set;}
}
Config config=configRoot.Get<Config>();
config.Nmae;
config.Proxy.Address;
选择方式读取配置
推荐使用IOptionsSnapshot进行配置的读取,确保一次请求的配置项,不会受到文件修改而修改
Nuget:
Microsoft.Extensions.Options
Microsoft.Extensions.Configuration.Binder
读取配置时,DI要声明IOptions<T>,IOptionsMonitor<T>,IOptionSnapshot<T>
IOptions<T>不会读到最新值,IOptionsMonitor<T>,IOptionSnapshot<T>相比
在一个范围内,读的值不会改变。
总之使用IOptionSnapshot<T>比较安全,主要使用此就行。
//使用IOptionsSnapshot进行获取配置
class TestController
{
//Config是一个json类型的配置文件
private readonly IOptionsSnapshot<Config> optConfig;
public TextController(IOptionsSnapshot<Config> optConfig)
{
this.optConfig=optConfig;
}
public void Test()
{
Console.WriteLine(optConfig.Value.Age);
}
}
//使用DI注入功能
private static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection();
//configRoot绑定到根节点
IConfigurationRoot configRoot=configBuilder.Build();
services.AddOptions().Configure<Config>(e=>configRoot.Bind(e));
service.AddScoped<TestController>();
// 1.创建服务集合2.向集合中注册服务,3.创建一个服务提供器
//第一个根对象只能用ServiceLocation的方式进行
using (var sp = services.BuildServiceProvider())
{
var c=sp.GetRequiredService<TestController>();
c.Test();
};
Console.ReadKey();
}
其他配置提供者
命令行方式配置
使用场景Docker
除了json的文件配置,还有其他类型的文件配置可以使用
Nuget
Microsoft.Extensions.Configuration.CommandLine
//使用DI注入功能
private static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection();
//configRoot绑定到根节点
services.AddOptions().Configure
private static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection();
service.AddScoped<TestController>();
comfigBuilder.AddCommandLine(args);
IConfigurationRoot configRoot=configBuilder.Build();
services.AddOptions().Configure<Config>(e=>configRoot.Bind(e));
using (var sp = services.BuildServiceProvider())
{
var c=sp.GetRequiredService<TestController>();
c.Test();
};
Console.ReadKey();
}
扁平化配置
对于复杂结构,要进行扁平化配置
{
"name":"yzk",
"age":"18",
"proxy":{
"address":"aa",
"port":"80",
"ids":[3,5,8]
}
}
在命令行方式提供参数
name=yzk age=18 proxy:address=aaa proxy:port=80
proxy:ids:0=3 proxy:ids:1=5 proxy:ids:3=8
//使用IOptionsSnapshot进行获取配置
class TestController
{
//Config是一个json类型的配置文件
private readonly IOptionsSnapshot<Config> optConfig;
public TextController(IOptionsSnapshot<Config> optConfig)
{
this.optConfig=optConfig;
}
public void Test()
{
Console.WriteLine(optConfig.Value.Age);
Console.WriteLine(optConfig.Value.Name);
Console.WriteLine(optConfig.Value.proxy.Address);
Console.WriteLine(optConfig.Value.proxy.Port);
Console.WriteLine(string.Join(",",optConfig.Value.proxy.ids));
}
}
环境变量的配置和命令行方式差不多,都是扁平化配置。
获取环境变量的配置使用
Microsoft.Extensions.Configuration.EnvironmentVariables
获取配置的环境变量
private static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection();
service.AddScoped<TestController>();
//==========================
//comfigBuilder.AddEnvironmentVariables();
//还可以允许添加前缀,避免和系统里其他的环境变量冲突
comfigBuilder.AddEnvironmentVariables("C1_");
IConfigurationRoot configRoot=configBuilder.Build();
services.AddOptions().Configure<Config>(e=>configRoot.Bind(e));
using (var sp = services.BuildServiceProvider())
{
var c=sp.GetRequiredService<TestController>();
c.Test();
};
Console.ReadKey();
}
其他配置源
还可以使用ini,xml,yaml等格式
中心化配置服务器Apollo,Nacos等开源服务器,或者使用Azure,阿里云等的配置服务。
造轮子 配置的提供者
标签:optConfig,string,int,配置,学习,中科,proxy,services,跟着 From: https://www.cnblogs.com/guan-tou6/p/182326411、开发一个直接或者间接实现IConfigurationProvider接口的类
XXXConfigurationProvider,一般继承自ConfigurationProvider。
如果是从文件读取,可以继承自FileConfigurationProvider。
重写Load方法,把“扁平化数据”设置到Data属性即可。2、再开发一个实现了IConfigurationSource接口的类XXXConfigurationSource。
如果是从文件读取,可以继承自FileConfigurationSource。在Build方法中返回
上面的ConfigurationProvider对象。3、然后使用即可,configurationBuilder.Add(new ConfigurationSource())即可。
为了简化使用,一般提供一个IConfigurationBuilder的扩展方法。整体流程:编写ConfigurationProvider类实际读取配置;
编写ConfigurationSource在Build中返回ConfigurationProvider对象;
把ConfigurationSource对象加入IConfigurationBuilder。