C# 文档随笔-1

本文最后更新于:2024年4月22日 凌晨

C# 文档

语言参考

运算符和表达式

Lambda 表达式和匿名函数

任何 Lambda 表达式都可以转换为委托类型。

Interlocked Class

可以为那些被多个线程共享的变量提供原子操作,如:InterLocked.Add方法,接受两个参数,第一个参数为ref引用参数,以原子操作的形式,添加两个整数并用两者的和替换第一个整数。
更多信息参考:Interlocked Class

C# 概念

属性(Property)

将特性附加到自动实现的属性

有一些特性例如NonSerializedAttribute只能附加到字段,不能附加到属性。可使用特性上的field:说明符将NonSerializedAttribute附加到属性的支持字段。

在属性值发生改变时触发事件

INotifyPropertyChanged接口用于通知数据绑定客户端值已更改。实现INotifyPropertyChanged接口,当属性值发生改变时,该对象会引发INotifyPropertyChanged.PropertyChanged事件来指示更改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ExampleClass : INotifyPropertyChanged
{
public int Number
{
get => _number;
set
{
if (value != _number)
{
_number = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Number)));
}
}
}
private int _number;

public event PropertyChangedEventHandler? PropertyChanged;
}

记录(Record)

本质上是语法糖,C#会自动将record转换为一个实现了EqualsGetHashCodeToString等方法的class

何时使用记录

  1. 想要定义依赖值相等性的数据模型(对记录来说,值相等性表示当类型匹配且所有属性和字段值都匹配时,记录类型的两个变量相等)
  2. 想要定义对象不可变的类型

可读写的属性

1
2
3
4
public record Person(string LastName)
{
public string FirstName { get; set; }
}

为属性提供额外的构造方法

1
2
3
4
5
6
7
public record User(string UserName, string? Email, int Age)
{
public User(string userName, int age) :this(userName, null, age)
{

}
}

使用with关键字快速创建副本

1
2
User u1 = new User{ "Zack", "yzk@example.com", 18 };
User u2 = u1 with { Email = "test@example" };

不可变性

即对象实例化后无法更改该对象的任何属性和字段值(具有不可变性的对象都是线程安全的,且 Hashcode 也不会变)

ToString

记录的ToString()方法会创建一个格式字符串,它显示对象的类型名称及其所有公共属性的名称和值。(顺带一提,ToString方法的默认实现是返回类型的完全限定名称

C# 编程指南

委托和事件

语句、表达式和相等性

关于Equals

如果在引用类型使用Equals()方法的话,默认行为是执行引用相等性比较,而不是值相等性比较。

日志

.NET 應用程序中的日志記錄和跟蹤

除了使用System.Console,還可以使用System.Diagnostics.DebugSystem.Diagnostics.Trace,這樣不僅可以輸出到控制臺,還能在附加了相應的偵聽器時寫入日志。

定義 TRACE 和 DEBUG 常數

默認情況下,當應用程序在調試模式下運行時,將定義DEBUG常數,也可以自行在csproj中添加DefineConstants條目進行控制:

1
2
3
4
5
6
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>

使用 Trace 與 Debug 類

1
2
3
Debug.Write("Debug - ");
Trace.WriteLine("This is a trace message when tracing the app.");
Debug.WriteLineIf(count == 0, "The count is 0 and this may cause an exception.");

此外還提供了Assert方法:

1
Debug.Assert([condition], [description]);

文件與目錄

文件路徑

獲取程序(當前)運行目錄:Console.WriteLine(Directory.GetCurrentDirectory());
獲取系統特殊文件夾目錄:string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
如果需要手動生成路徑時,建議不要硬編碼路徑字符(除非應用只運行在特定的操作系統上),而是使用Path.DirectorySeparatorCharConsole.WriteLine($"stores{Path.DirectorySeparatorChar}201");
或者使用Path.Combine()方法來生成正確的特定操作系統路徑:Console.WriteLine(Path.Combine("stores","201"));

读取和写入

如果在写入某些数据的时候需要换行,请使用:Environment.NewLine

Json、Xml

包:Newtonsoft.Json

csv

包:CsvHelper

正则表达式(規則運算式)

中心物件:Sytem.Text.RegularExpressions.Regex
使用正則表達式來處理字符串時,一般都是提供兩個信息:

  1. 待處理的字符串
  2. 正則表達式模式
    常用的操作有:
  • Regex.IsMatch: 判斷模式是否出現在字符串中
  • Regex.Match/Regex.Matches: 獲取字符串中符合模式的匹配項。前者回傳Match物件,後者回傳MatchCollection物件
  • Regex.Replace: 將字符串中符合模式的文本進行替換

使用正則表達式需要注意的地方

  1. 在正则表达式中,捕获组用来捕获匹配到的子字符串。当你使用括号()来包裹一个部分时,这个部分就会成为一个捕获组。在Match对象中,捕获组的索引是从1开始的,而不是从0开始,因为索引0表示整个匹配的字符串。所以match.Groups[0].Value的值和match.Value的值是一樣的。
  2. 注意反斜杠\的使用。在正則表達式中,反斜杠\是用來轉義特殊字符的,但是在CSharp中,反斜杠\也是一個特殊字符,用來表示轉義序列,在字符串中,想要表示一個反斜杠,實際上是\\,所以在一般的字符串中,需要寫成如:"\\."來匹配一個句點。但是字符串前加上@,將其變爲“原始字符串字面值”,則不會進行轉義處理,此時就應寫成:@"\."

这里有一只爱丽丝

希望本文章能够帮到您~


C# 文档随笔-1
https://map1e-g.github.io/2023/12/07/CSharp-essay-1/
作者
MaP1e-G
发布于
2023年12月7日
许可协议