从 C# 基础到掌握 — 第 3 集
了解类、结构、记录和空安全
该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。
在 C# 中,数据可以表示为类、结构和记录。 即使语法相似,复制方法和同一性的含义也不同,所以必须根据目的来选择。
类是引用类型
public sealed class Player
{
public string Name { get; }
public int Health { get; private set; }
public Player(string name, int health)
{
Name = name;
Health = health;
}
}
Player first = new("Rose", 100);
Player second = first;
在第二种情况下,复制指向同一对象的引用,而不是整个对象。 如果您更改一侧的生命值,您可以在另一侧看到更改后的结果。
struct 是一个值类型
public readonly struct Position
{
public float X { get; }
public float Y { get; }
public Position(float x, float y)
{
X = x;
Y = y;
}
}
当您分配一个结构时,该值将被复制。 它适用于较小且被视为单个值的数据,例如坐标或颜色。
大型结构具有更高的复制成本,并且可变结构可能会产生不可预测的行为。 结构体不一定很快。
record 自己比较值
public sealed record ItemKey(int Id, string Grade);
var a = new ItemKey(10, "Rare");
var b = new ItemKey(10, "Rare");
Console.WriteLine(a == b); // True
一般类基本上是比较引用是否相同,而记录则是比较配置值是否相同。 它非常适合与不可变数据(例如设置、命令和网络消息)一起使用。
将类型标记为可为空
Player? FindPlayer(int id)
{
return players.TryGetValue(id, out Player? player)
? player
: null;
}
Player? target = FindPlayer(10);
if (target is not null)
{
Console.WriteLine(target.Name);
}
使用可为空的引用类型,您可以区分可为空的引用和不可为空的引用。 在使用 ! 清除警告之前,您需要再次检查流程,看看 null 是否真的不可能。
类、结构和记录的选择不是偏好问题。 你必须首先决定对象的身份是否重要,值的复制是否是自然的,或者它是否是不可变的数据。