CSharp8.0
c# 8.0是专门面向.net core的第一个c#版本,一些功能依赖于新的CLR功能,而其他功能依赖于仅在net core中添加的库类型。
默认接口方法
//接口里也可以定义方法实现,并且可以使用public修饰
public interface IStudent
{
public int GetAge();
public string GetName()
{
return "张三同学";
}
}
switch属性模式
public static decimal ComputeSalesTax(Address location, decimal salePrice) => (location) switch
{
{ State: "WA" } => salePrice * 0.064M,
{ State: "MN" } => salePrice * 0.075M,
{ State: "MI" } => salePrice * 0.05M,
_ => 0M
}
public class Address
{
public string? State { get; set; }
}
元组模式
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"
}
位置模式
public static Quadrant GetQuadrant(Point point) => point switch
{
(0, 0) => Quadrant.Origin,
var (x, y) when x > 0 && y > 0 => Quadrant.One,
var (x, y) when x < 0 && y > 0 => Quadrant.Two,
var (x, y) when x < 0 && y < 0 => Quadrant.Three,
var (x, y) when x > 0 && y < 0 => Quadrant.Four,
var (_, _) => Quadrant.OnBorder,
};
public struct Point
{
public double X { get; set; }
public double Y { get; set; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out double x, out double y) =>
(x, y) = (X, Y);
public double Distance => Math.Sqrt(X * X + Y * Y);
public readonly override string ToString() =>
$"({X}, {Y}) is {Distance} from the origin";
}
异步流支持
public static async Task GetAsyncData()
{
await foreach (var number in GetNewAsyncIntList())
{
Console.WriteLine(number);
}
}
//IAsyncEnumerable异步的Enumerable类
public static async IAsyncEnumerable<int> GetNewAsyncIntList()
{
for (int i = 0; i < 20; i++)
{
await Task.Delay(100);
yield return i;
}
}
索引和范围
//索引和范围
{
string[] words = new string[]
{
"The",
"quick",
"brown",
"fox",
"jumped",
"over",
"the",
"lazy",
"dog"
};
var quickBrownFox = words[1..4];//从左到右【从0开始】,返回值尾数组
string message3 = words[^1];//从尾到头【^1就是右面的第一个】,返回的字符串
Range phrase = 1..4; //定义一个范围
var text = words[phrase]; //使用范围
}
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
CSharp9.0
c#9随着dotnet5一起发布。它是面向.NET5版本的任何程序集的默认语言版本。
记录类型
public record Person1(string FirstName, string LastName);
//使用init,初始化后不能修改属性
public record Person2
{
public string FirstName { get; init; } = default!;
public string LastName { get; init; } = default!;
};
//可以修改属性
public record Person3
{
public string FirstName { get; set; } = default!;
public string LastName { get; set; } = default!;
};
public record Person4(string FirstName, string LastName, string[] PhoneNumbers);
public record Person5(string FirstName, string LastName)
{
public string[] PhoneNumbers { get; init; }
}
//抽象记录
public abstract record Person6(string FirstName, string LastName);
public record Teacher(string FirstName, string LastName, int Grade)
: Person6(FirstName, LastName);
值相等性
var phoneNumbers = new string[2];
Person4 person1 = new("Nancy", "Davolio", phoneNumbers);
Person4 person2 = new("Nancy", "Davolio", phoneNumbers);
Console.WriteLine(person1 == person2); // output: True,校验的数据是否相同
//内存中对象引用是否相同?
Console.WriteLine(ReferenceEquals(person1, person2)); // output: False
非破坏性修改
//person的属性无法直接修改
Person5 person1 = new("Nancy", "Davolio") { PhoneNumbers = new string[1] };
//通过with得到另外一个实例
Person5 person2 = person1 with { FirstName = "John" };
仅限 Init 的资源库
//普通类使用Init修饰,把类当成资源来使用
public Class 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";
}
模式匹配增强功能
C# 9 包括新的模式匹配改进:
类型模式 与对象匹配特定类型
带圆括号的模式强制或强调模式组合的优先级
联合 and 模式要求两个模式都匹配
析取 or 模式要求任一模式匹配
否定 not 模式要求模式不匹配
关系模式要求输入小于、大于、小于等于或大于等于给定常数。
public static class Extension
{
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 ',';
}
扩展GetEnumerator方法来实现foreach
Person[] PersonList = new Person[3]
{
new ("John", "Smith"),
new ("Jim", "Johnson"),
new ("Sue", "Rabon"),
};
People people = new People(PersonList);
//之前的遍历,必须要实现IEnumerator接口,现在可以扩展一个GetEnumerator方法来实现遍历
foreach (var person in people)
{
Console.WriteLine(person);
}
public record Person(string FirstName, string LastName);
public class People
{
int position = -1;
private Person[] _people { get; init; }
public People(Person[] people)
{
_people = people;
}
public bool MoveNext()
{
position++;
return (position < _people.Length);
}
public object Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}
public static class PeopleExtensions
{
//public static IEnumerator<T> GetEnumerator<T>(this IEnumerator<T> people) => people;
public static People GetEnumerator(this People people) => people;
}