C#知多少 | 每个版本都更新了什么?

总所周知,.NET5.0马上就要来了,最后一个预览版RC2也已经发布了,在11月的时候,我们就正式的发布了,然后我们就可以迁移使用了,当然今天说的重点不是.NET,今天说的是伴随着.NET5一起到来的C#9.0,既然要了解9.0,肯定要对之前的版本也稍微了解一下,至少不会面试的时候出现:XXX这个功能用过么,哪个版本出来的知道么?一问三不知的尴尬情景。虽然官网都有,但是我相信有一小部分不看,所以还是发出来吧。

咱们就采用从小到大的顺序讲解吧,从6.0开始,5.0就太老了,基本不会问了,注意是C#,不是MVC,查看的都是官网的,想看更多,点击【阅读原文】。


C#6中新增的功能

1get 只读属性

简洁的语法来创建不可变类型,仅有get访问器:

public string FirstName { get; }
public string LastName { get;  }

当然很多时候,我们使用的是私有化来设置set。

然后通过构造函数来赋值:

public Student(string firstName, string lastName)
{if (IsNullOrWhiteSpace(lastName))throw new ArgumentException(message: "Cannot be blank", paramName: nameof(lastName));FirstName = firstName;LastName = lastName;
}

2get 属性初始化表达式

在属性声明中声明自动属性的初始值,

public ICollection<double> Grades { get; } = new List<double>();

声明处就可以直接被初始化。

3Expression-bodied 函数成员

这适用于方法和只读属性。 例如,重写 ToString() 通常是理想之选:

public override string ToString() => $"{LastName}, {FirstName}";

也可以将此语法用于只读属性:

public string FullName => $"{FirstName} {LastName}";

4using 静态命名空间

using static  增强功能可用于导入单个类的静态方法。 指定要使用的类:

using static System.Math;

在 LINQ 查询中会经常看到这种情况。 可以通过导入 Enumerable 或 Queryable 来导入 LINQ 模式。

5Null 条件运算符

Null 条件运算符使 null 检查更轻松、更流畅  。 将成员访问 . 替换为 ?.

var first = person?.FirstName;

如果person为空,返回的值就是null,是string的默认值,如果FirstName是int类型,那返回的就是int的默认值0。

6$ 字符串内插

新的字符串内插功能可以在字符串中嵌入表达式。 使用 $ 作为字符串的开头,并使用 {} 之间的表达式代替序号:

public string GetGradePointPercentage() =>$"Name: {LastName}, {FirstName}. G.P.A: {Grades.Average():F2}";

上一行代码将 Grades.Average() 的值格式设置为具有两位小数的浮点数。

7when 异常筛选器

“异常筛选器”是确定何时应该应用给定的catch子句的子句 。如果用于异常筛选器的表达式计算结果为true,则catch子句将对异常执行正常处理。 如果表达式计算结果为false,则将跳过catch子句。一种用途是检查有关异常的信息,以确定catch子句是否可以处理该异常:

public static async Task<string> MakeRequest()
{WebRequestHandler webRequestHandler = new WebRequestHandler();webRequestHandler.AllowAutoRedirect = false;using (HttpClient client = new HttpClient(webRequestHandler)){var stringTask = client.GetStringAsync("https://docs.microsoft.com/en-us/dotnet/about/");try{var responseText = await stringTask;return responseText;}catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301")){return "Site Moved";}}
}

8nameof 表达式

nameof 表达式的计算结果为符号的名称。 每当需要变量、属性或成员字段的名称时,这是让工具正常运行的好办法,说白了就是更好的重构:

if (IsNullOrWhiteSpace(lastName))throw new ArgumentException(message: "Cannot be blank", paramName: nameof(lastName));

9Catch 和 Finally 块中的 Await

现在可以在 catchfinally 表达式中使用 await。 这通常用于日志记录方案:

public static async Task<string> MakeRequestAndLogFailures()
{await logMethodEntrance();var client = new System.Net.Http.HttpClient();var streamTask = client.GetStringAsync("https://localHost:10000");try {var responseText = await streamTask;return responseText;} catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301")){await logError("Recovered from redirect", e);return "Site Moved";}finally{await logMethodExit();client.Dispose();}
}

10索引器初始化关联集合

可以将集合初始值设定项与 Dictionary<TKey,TValue> 集合和其他类型一起使用,在这种情况下,可访问的 Add 方法接受多个参数。 新语法支持使用索引分配到集合中:

private Dictionary<int, string> webErrors = new Dictionary<int, string>
{[404] = "Page not Found",[302] = "Page moved, but left a forwarding address.",[500] = "The web server can't come out to play today."
};

C#7.x 中新增的功能

1out 变量

可以在方法调用的参数列表中声明 out 变量,而不是编写单独的声明语句::

if (int.TryParse(input, out int result))Console.WriteLine(result);
elseConsole.WriteLine("Could not parse input");

为清晰明了,可能需指定 out 变量的类型,如上所示。 但是,该语言支持使用隐式类型的局部变量:

if (int.TryParse(input, out var answer))Console.WriteLine(answer);
elseConsole.WriteLine("Could not parse input");

2Tuple 元组

低于 C# 7.0 的版本中也提供元组,但它们效率低下且不具有语言支持。这意味着元组元素只能作为 Item1 和 Item2 等引用。

可以通过为每个成员赋值来创建元组,并可选择为元组的每个成员提供语义名称:

(string Alpha, string Beta) namedLetters = ("a", "b");
Console.WriteLine($"{namedLetters.Alpha}, {namedLetters.Beta}");

在进行元组赋值时,还可以指定赋值右侧的字段的名称:

var alphabetStart = (Alpha: "a", Beta: "b");
Console.WriteLine($"{alphabetStart.Alpha}, {alphabetStart.Beta}");

使用的时候,可以直接点出来:

alphabetStart.Alpha
alphabetStart.Beta

3_ 弃元

C# 增添了对弃元的支持。 弃元是一个名为 _(下划线字符)的只写变量,可向单个变量赋予要放弃的所有值。 弃元类似于未赋值的变量;不可在代码中使用弃元(赋值语句除外):

public class Example
{public static void Main(){var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");}private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int year2){int population1 = 0, population2 = 0;double area = 0;if (name == "New York City"){area = 468.48;if (year1 == 1960){population1 = 7781984;}if (year2 == 2010){population2 = 8175133;}return (name, area, year1, population1, year2, population2);}return ("", 0, 0, 0, 0, 0);}
}

4is 模式匹配

模式匹配支持 is 表达式和 switch 表达式。 每个表达式都允许检查对象及其属性以确定该对象是否满足所寻求的模式。 使用 when 关键字来指定模式的其他规则:

public static int SumPositiveNumbers(IEnumerable<object> sequence)
{int sum = 0;foreach (var i in sequence){switch (i){case 0:break;case IEnumerable<int> childSequence:{foreach(var item in childSequence)sum += (item > 0) ? item : 0;break;}case int n when n > 0:sum += n;break;case null:throw new NullReferenceException("Null found in sequence");default:throw new InvalidOperationException("Unrecognized type");}}return sum;
}
  • case 0: 是常见的常量模式。

  • case IEnumerable<int> childSequence: 是一种类型模式。

  • case int n when n > 0: 是具有附加 when 条件的类型模式。

  • case null: 是 null 模式。

  • default: 是常见的默认事例。

5本地函数(内部)

本地函数使你能够在另一个方法的上下文内声明方法。 本地函数使得类的阅读者更容易看到本地方法仅从声明它的上下文中调用。

public static IEnumerable<char> AlphabetSubset3(char start, char end)
{if (start < 'a' || start > 'z')throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");if (end < 'a' || end > 'z')throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");if (end <= start)throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}");return alphabetSubsetImplementation();IEnumerable<char> alphabetSubsetImplementation(){for (var c = start; c < end; c++)yield return c;}
}

注意上边的alphabetSubsetImplementation方法,是在内部定义的。

同样可以使用异步:

public Task<string> PerformLongRunningWork(string address, int index, string name)
{if (string.IsNullOrWhiteSpace(address))throw new ArgumentException(message: "An address is required", paramName: nameof(address));if (index < 0)throw new ArgumentOutOfRangeException(paramName: nameof(index), message: "The index must be non-negative");if (string.IsNullOrWhiteSpace(name))throw new ArgumentException(message: "You must supply a name", paramName: nameof(name));return longRunningWorkImplementation();async Task<string> longRunningWorkImplementation(){var interimResult = await FirstWork(address);var secondResult = await SecondStep(index, name);return $"The results are {interimResult} and {secondResult}. Enjoy.";}
}

当然也支持某些使用lambda表达式来完成。

6数字文本语法改进

C# 7.0 包括两项新功能,可用于以最可读的方式写入数字来用于预期用途:二进制文本和数字分隔符 。在创建位掩码时,或每当数字的二进制表示形式使代码最具可读性时,以二进制形式写入该数字:

public const int Sixteen =   0b0001_0000;
public const int ThirtyTwo = 0b0010_0000;
public const int SixtyFour = 0b0100_0000;
public const int OneHundredTwentyEight = 0b1000_0000;

常量开头的 0b 表示该数字以二进制数形式写入。 二进制数可能会很长,因此通过引入 _ 作为数字分隔符通常更易于查看位模式,如上面二进制常量所示。 数字分隔符可以出现在常量的任何位置。 对于十进制数字,通常将其用作千位分隔符:

public const long BillionsAndBillions = 100_000_000_000;

C#8.0中新增的功能

“.NET Core 3.x”和“.NET Standard 2.1”支持 C# 8.0;

1Readonly 成员

可将 readonly 修饰符应用于结构的成员。 它指示该成员不会修改状态。 这比将 readonly 修饰符应用于 struct 声明更精细。  请考虑以下可变结构:

public readonly double Distance => Math.Sqrt(X * X + Y * Y);

2默认接口方法

现在可以将成员添加到接口,并为这些成员提供实现。 借助此语言功能,API 作者可以将方法添加到以后版本的接口中,而不会破坏与该接口当前实现的源或二进制文件兼容性。 现有的实现继承默认实现。

public interface ICustomer
{IEnumerable<IOrder> PreviousOrders { get; }DateTime DateJoined { get; }DateTime? LastOrder { get; }string Name { get; }IDictionary<DateTime, string> Reminders { get; }
}

 

3Switch 表达式升级

通常情况下,switch 语句在其每个 case 块中生成一个值。借助 Switch 表达式,可以使用更简洁的表达式语法。

public static RGBColor FromRainbowClassic(Rainbow colorBand)
{switch (colorBand){case Rainbow.Red:return new RGBColor(0xFF, 0x00, 0x00);case Rainbow.Orange:return new RGBColor(0xFF, 0x7F, 0x00);case Rainbow.Yellow:return new RGBColor(0xFF, 0xFF, 0x00);case Rainbow.Green:return new RGBColor(0x00, 0xFF, 0x00);case Rainbow.Blue:return new RGBColor(0x00, 0x00, 0xFF);case Rainbow.Indigo:return new RGBColor(0x4B, 0x00, 0x82);case Rainbow.Violet:return new RGBColor(0x94, 0x00, 0xD3);default:throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand));};
}

这里有几个语法改进:

  • 变量位于 switch 关键字之前。 不同的顺序使得在视觉上可以很轻松地区分 switch 表达式和 switch 语句。

  • case: 元素替换为 =>。 它更简洁,更直观。

  • default 事例替换为 _ 弃元。

  • 正文是表达式,不是语句。

public static RGBColor FromRainbow(Rainbow colorBand) =>colorBand switch{Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),_              => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),};

4属性模式

借助属性模式,可以匹配所检查的对象的属性。 请看一个电子商务网站的示例,该网站必须根据买家地址计算销售税。 这种计算不是 Address 类的核心职责。 它会随时间变化,可能比地址格式的更改更频繁。 销售税的金额取决于地址的 State 属性。 下面的方法使用属性模式从地址和价格计算销售税:

public static decimal ComputeSalesTax(Address location, decimal salePrice) =>location switch{{ State: "WA" } => salePrice * 0.06M,{ State: "MN" } => salePrice * 0.075M,{ State: "MI" } => salePrice * 0.05M,// other cases removed for brevity..._ => 0M};

在 LINQ 查询中会经常看到这种情况。 可以通过导入 Enumerable 或 Queryable 来导入 LINQ 模式。

5元组模式

一些算法依赖于多个输入。 使用元组模式,可根据表示为元组的多个值进行切换。  以下代码显示了游戏“rock, paper, scissors(石头剪刀布)”的切换表达式::

public static string RockPaperScissors(string first, string second)=> (first, second) switch{("rock", "paper") => "rock is covered by paper. Paper wins.",("rock", "scissors") => "rock breaks scissors. Rock wins.",("paper", "rock") => "paper covers rock. Paper wins.",("paper", "scissors") => "paper is cut by scissors. Scissors wins.",("scissors", "rock") => "scissors is broken by rock. Rock wins.",("scissors", "paper") => "scissors cuts paper. Scissors wins.",(_, _) => "tie"};

如果person为空,返回的值就是null,是string的默认值,如果FirstName是int类型,那返回的就是int的默认值0。

6using 声明

using 声明是前面带 using 关键字的变量声明。 它指示编译器声明的变量应在封闭范围的末尾进行处理。 以下面编写文本文件的代码为例:

static int WriteLinesToFile(IEnumerable<string> lines)
{using var file = new System.IO.StreamWriter("WriteLines2.txt");// Notice how we declare skippedLines after the using statement.int skippedLines = 0;foreach (string line in lines){if (!line.Contains("Second")){file.WriteLine(line);}else{skippedLines++;}}// Notice how skippedLines is in scope here.return skippedLines;// file is disposed here
}

前面的代码相当于下面使用经典 using 语句的代码:

static int WriteLinesToFile(IEnumerable<string> lines)
{// We must declare the variable outside of the using block// so that it is in scope to be returned.int skippedLines = 0;using (var file = new System.IO.StreamWriter("WriteLines2.txt")){foreach (string line in lines){if (!line.Contains("Second")){file.WriteLine(line);}else{skippedLines++;}}return skippedLines;} // file is disposed here
}

7Static 静态本地函数

现在可以向本地函数添加 static 修饰符,以确保本地函数不会从封闭范围捕获(引用)任何变量。

int M()
{ int y = 5;int x = 7;return Add(x, y);static int Add(int left, int right) => left + right;
}

8async 异步流

从 C# 8.0 开始,可以创建并以异步方式使用流。返回异步流的方法有三个属性:

  1. 它是用 async 修饰符声明的。

  2. 它将返回 IAsyncEnumerable<T>。

  3. 该方法包含用于在异步流中返回连续元素的 yield return 语句。

public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()
{for (int i = 0; i < 20; i++){await Task.Delay(100);yield return i;}
}await foreach (var number in GenerateSequence())
{Console.WriteLine(number);
}

异步可释放:

从 C# 8.0 开始,语言支持实现 System.IAsyncDisposable 接口的异步可释放类型。可使用 await using 语句来处理异步可释放对象。

9索引和范围

范围指定范围的开始和末尾 。 包括此范围的开始,但不包括此范围的末尾,这表示此范围包含开始但不包含末尾 。 范围 [0..^0] 表示整个范围,就像 [0..sequence.Length] 表示整个范围。

请看以下几个示例。 请考虑以下数组,用其顺数索引和倒数索引进行注释:

var words = new string[]
{// index from start    index from end"The",      // 0                   ^9"quick",    // 1                   ^8"brown",    // 2                   ^7"fox",      // 3                   ^6"jumped",   // 4                   ^5"over",     // 5                   ^4"the",      // 6                   ^3"lazy",     // 7                   ^2"dog"       // 8                   ^1
};              // 9 (or words.Length) ^0// 可以使用 ^1 索引检索最后一个词:
Console.WriteLine($"The last word is {words[^1]}");
// writes "dog"

以下代码创建了一个包含单词“quick”、“brown”和“fox”的子范围。 它包括 words[1]words[3]。 元素 words[4] 不在该范围内。

var quickBrownFox = words[1..4];var allWords = words[..]; // contains "The" through "dog".
var firstPhrase = words[..4]; // contains "The" through "fox"
var lastPhrase = words[6..]; // contains "the", "lazy" and "dog"

10null 合并赋值

C# 8.0 引入了 null 合并赋值运算符 ??=。 仅当左操作数计算为 null 时,才能使用运算符 ??= 将其右操作数的值分配给左操作数。

List<int> numbers = null;
int? i = null;numbers ??= new List<int>();
numbers.Add(i ??= 17);
numbers.Add(i ??= 20);Console.WriteLine(string.Join(" ", numbers));  // output: 17 17
Console.WriteLine(i);  // output: 17

C#9.0 中新增的功能

.NET5支持C#9.0.

1记录类型

C# 9.0 引入了记录类型,这是一种引用类型,它提供合成方法来提供值语义,从而实现相等性。 默认情况下,记录是不可变的。

public record Person
{public string LastName { get; }public string FirstName { get; }public Person(string first, string last) => (FirstName, LastName) = (first, last);
}

2Init 仅限的资源库

从 C# 9.0 开始,可为属性和索引器创建 init 访问器,而不是 set 访问器。 调用方可使用属性初始化表达式语法在创建表达式中设置这些值,但构造完成后,这些属性将变为只读。 仅限 init 的资源库提供了一个窗口用来更改状态。

public struct WeatherObservation
{public DateTime RecordedAt { get; init; }public decimal TemperatureInCelsius { get; init; }public decimal PressureInMillibars { get; init; }public override string ToString() =>$"At {RecordedAt:h:mm tt} on {RecordedAt:M/d/yyyy}: " +$"Temp = {TemperatureInCelsius}, with {PressureInMillibars} pressure";
}

调用方可使用属性初始化表达式语法来设置值,同时仍保留不变性:

var now = new WeatherObservation 
{ RecordedAt = DateTime.Now, TemperatureInCelsius = 20, PressureInMillibars = 998.0m 
};

3顶级语句

顶级语句从许多应用程序中删除了不必要的流程。只有一行代码执行所有操作。 借助顶级语句,可使用 using 语句和执行操作的一行替换所有样本:

using System;Console.WriteLine("Hello World!");

如果需要单行程序,可删除 using 指令,并使用完全限定的类型名称:

System.Console.WriteLine("Hello World!");

4模式匹配增强功能

C# 9 包括新的模式匹配改进:

  • 类型模式要求在变量是一种类型时匹配

  • 带圆括号的模式强制或强调模式组合的优先级

  • 联合 and 模式要求两个模式都匹配

  • 析取 or 模式要求任一模式匹配

  • 求反 not 模式要求模式不匹配

  • 关系模式要求输入小于、大于、小于等于或大于等于给定常数。

public static bool IsLetter(this char c) =>c is >= 'a' and <= 'z' or >= 'A' and <= 'Z';public static bool IsLetterOrSeparator(this char c) =>c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';    

 

5调试和完成功能

在 C# 9.0 中,已知创建对象的类型时,可在 new 表达式中省略该类型。 最常见的用法是在字段声明中:

private List<WeatherObservation> _observations = new();

当需要创建新对象作为参数传递给方法时,也可使用目标类型 new。 请考虑使用以下签名的 ForecastFor() 方法:

public WeatherForecast ForecastFor(DateTime forecastDate, WeatherForecastOptions options)

可按如下所示调用该方法:

var forecast = station.ForecastFor(DateTime.Now.AddDays(2), new());

好啦,关于c#的更新呢,暂时就这么多了,看着很长,其实很多咱们平时都已经使用到了,当然还有一些不太常用的我没有去列举,更多的内容,左下角点击【阅读原文】吧。




BCVP开发者社区推荐

欢迎你来

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode40. 组合总和 II(树层去重)

一:题目 二:上码 class Solution {/**注意这里的去重:1.我们分为树层去重比如[1,1 2,5] target 8,那么如果我们用树枝去重的话,那么就会出现[1,2,5],[1,2,5]那么的话我们就需要树层去重 就是横向遇见相同的元素跳过。2.树枝去重的 树枝去重就是 我们数组前面使用过的元素不…

WPF开源控件扩展库 - MaterialDesignExtensions

WPF开源控件扩展库 - MaterialDesignExtensionsMaterialDesignExtensions仓库截图logoMaterial Design Extensions 在WPF开源控件库 ????Material Design in XAML Toolkit(本站介绍&#xff1a;????链接)的基础上进行了控件扩展和特性新增。本开源项目中的控件或许不在…

leetcode131. 分割回文串

一:题目 二:上码 class Solution {/**思路:1.纵向递归的话 我们递归深度是 我们的 切割线切到了最后 2.横向for 我们的宽度就是字符串宽度3.在哪截取的话 那就是在哪个坐标的后面*/List<List<String>> ans new ArrayList<>();List<String> path n…

WordPress 已过时?创始人与新架构拥护者开战

喜欢就关注我们吧&#xff01;近日&#xff0c;WordPress 创始人 Matt Mullenweg 与 Netlify 首席执行官 Matt Biilmann 展开了一场口水战&#xff0c;双方就 WordPress 与新兴 WEB 应用架构 JAMStack 孰优孰劣进行了激烈的辩论。何为 JAMStack?JAMStack 是一种将 Web 应用部署…

leetcode93. 复原 IP 地址(思路+详解)

一:题目 二:上码 class Solution {/**思路: 1.跟分割字符串差不多,但是我们需要记录添加的.的个数 当其个数等于3的时候 我们就已经切割成4段了。2.判断字符是否合法1>:以0开头的数字不合法2>:遇见非数字字符不合法3>:大于255不合法*/private List<String> an…

今天的你,又被带节奏了吗?

这是头哥侃码的第220篇原创十一期间&#xff0c;我在某微信群看到几个哥们在讨论 与「带节奏」有关的话题。很显然&#xff0c;像这种略带吐槽的的话题是很容易引起共鸣的。于是你一句他一句的&#xff0c;用自带表情包的方式开始说起了「带节奏」的各种操作。先是A君&#xff…

谷歌最终还是把Knative交了出来

谷歌方面正计划将其开源 Knative 项目的直接控制权让渡给一个指导委员会。Knative 是谷歌开源的一套 Serverless 架构方案&#xff0c;它扩展了 Kubernetes&#xff0c;专注于解决容器为核心的 Serverless 应用的构建、部署和运行的问题&#xff0c;它构建在 Kubernetes 和 Ist…

你那么普通 所以一定要自信啊

你这么普通&#xff0c;必须自信啊 ​ 昨天讲到&#xff0c;不管你准没准备好&#xff0c;该来的都来了。只要你进入了社会&#xff0c;这一切都没得选&#xff0c;好的坏的甭管啥事&#xff0c;都一股脑摆在你面前&#xff0c;你必须要处理。你说我不行啊&#xff0c;我做不到…

leetcode293周赛6064. 不含特殊楼层的最大连续楼层数

一:题目 二:上码 // class Solution { // public:// bool find(vector<int>& v,int i) { // for (auto nums:v) { // if (nums i) return true;//包含某个数 就返回true // } // return false; // }// int maxCon…

leetcode293周赛5234. 移除字母异位词后的结果数组

一:题目 二:上码 class Solution { public:/**1.所谓字母异位词就是相同的字母组成的字符串&#xff08;这个字符串可以相同&#xff09;2.首先判断两个字符串中的字母是否相同用map进行计数&#xff0c;然后在另一个字符串中查找某个字符进行--;3.如果最终的map中所有的value…

七国要求科技巨头预留后门 应对马甲芯片高度警惕

日前&#xff0c;美国、英国、日本、澳大利亚、加拿大、新西兰、印度呼吁科技公司设计产品时确保政府可以访问经过加密的消息和内容。其实&#xff0c;西方科技公司配合西方政府在产品中预留后门早已不是新鲜事&#xff0c;斯诺登就曾经爆料多个美国科技巨头配合美国情报部门收…

leetcode78. 子集

一:题目 二:上码 class Solution {/**横向递归的是:我们子集的长度纵向递归的是:我们子集的中元素的更改*/List<List<Integer>> ans new ArrayList<>();List<Integer> path new ArrayList<>();public void getAns(int[] nums,int st) {ans.ad…

跟我一起学Redis之看完这篇比常人多会三种类型实战(又搞了几个小时)

前言对于Redis而言&#xff0c;很多小伙伴只关注其关键的五大基础类型&#xff1a;string、hash、list、set、sorted set(有序集合)&#xff0c;其实还有三种特殊类型在很多应用场景也比较适合使用&#xff0c;分别是&#xff1a;bitmap、geospatial、hyperloglog&#xff1b;上…

leetcode90. 子集 II(树层去重)

一:题目 二:上码 class Solution {/**- 先排序- 树层去重:那么直接在从横向循环中去重即可*/List<List<Integer>> ans new ArrayList<>();List<Integer> path new ArrayList<>();public void getAns(int[] nums,int st) {ans.add(new ArrayLi…

Rancher 2.5 正式发布,多项重大更新来袭!

喜欢就关注我们吧&#xff01;近日&#xff0c;Kubernetes 管理平台 Rancher 2.5 正式发布&#xff0c;官方公布了在 Rancher 2.5 中的多项重大更新&#xff0c;包括全新的安装体验、针对边缘集群的大规模 GitOps 以及 EKS 集群的全生命周期管理。具体更新信息如下&#xff1a;…

leetcode491. 递增子序列(树层去重魔改版)

一:题目 二:上码 class Solution {/**思路:1.这里已经指明了不允许有重复的&#xff0c;那么树层去重 树枝去重(以前用过的元素不再使用)2.坑:这里不能用 传统的树层去重了 因为我们无法排序了3.这里给出的解决办法是 是利用 hashmap,对每个数出现的频率进行统计如果其频率…

数据结构与算法专题——第十二题 Trie树

今天来聊一聊Trie树&#xff0c;Trie树的名字有很多&#xff0c;比如字典树&#xff0c;前缀树等等。一&#xff1a;概念 下面有and,as,at,cn,com这几个关键词&#xff0c;构建成 trie 树如下。从上面图中&#xff0c;应该可以或多或少的发现一些好玩的特性。根节点不包含字符&…

leetcode46. 全排列

一:题目 二:上码 class Solution {/**1.全排列问题,我们的横向都是从0开始不再是st了 因为我们用到前面已经使用过的元素单是在纵向递归当中我们不能使用重复的元素&#xff0c;这里我们用used来去重。*/private List<List<Integer>> ans new ArrayList<>(…

leetcode47. 全排列 II

一:题目 二:上码 class Solution {private List<List<Integer>> ans new ArrayList<>();private List<Integer> path new ArrayList<>();private boolean[] used;public void getAns(int[] nums,boolean[] used) {if (path.size() nums.leng…

C# 很少人知道的科技

本文来告诉大家在C#很少有人会发现的科技。即使是工作了好多年的老司机也不一定会知道这些科技&#xff0c;如果觉得我是在骗你&#xff0c;那么请看看本文的内容。原本最初 C# 的设计是简单和高效开发的&#xff0c;在经过了这么多年众多公司和开发者的努力下&#xff0c;整个…