为何C#中int、char等值类型可用==比较,自定义struct却不行?
为什么自定义struct无法直接用
==比较,但int、char等内置值类型可以? 首先纠正一个错误认知:==运算符对于值类型的行为和存储位置(栈/堆)完全无关,也不是比较引用——值类型本身没有引用(引用类型才有引用地址),值类型的==本质是比较内容,但这个行为需要显式定义。
核心原因
- 内置值类型(int、char等):.NET框架已经为所有预定义值类型(如
int、char、bool)重载了==运算符,直接实现了值内容的比较逻辑,所以可以直接使用。 - 自定义struct:C#编译器不会自动为自定义struct生成
==运算符的默认实现。因为编译器无法判断你对“相等”的定义——是要求所有字段完全匹配?还是只比较部分关键成员?必须由开发者手动实现比较逻辑。
解决方法:为自定义struct重载==运算符
要让自定义struct支持==比较,需要手动重载==和!=运算符,同时建议重写Equals()和GetHashCode()方法,保证逻辑一致性:
public struct S1 { public int Id; public string Name; // 重载==运算符,自定义相等逻辑 public static bool operator ==(S1 left, S1 right) { return left.Id == right.Id && left.Name == right.Name; } // 必须同时重载!=运算符 public static bool operator !=(S1 left, S1 right) { return !(left == right); } // 重写Object.Equals,保持和==逻辑一致 public override bool Equals(object obj) { return obj is S1 other && this == other; } // 重写GetHashCode,适配哈希集合(如HashSet、Dictionary) public override int GetHashCode() { return HashCode.Combine(Id, Name); } }
补充:关于值类型的存储位置
你之前认为struct存在栈上是片面的:值类型的存储位置取决于它的上下文——作为局部变量时在栈上,作为类的成员字段时会和类对象一起存在堆上。但这个存储位置和==能否使用没有任何关联,核心还是==运算符是否被重载。
内容的提问来源于stack exchange,提问作者Islam AbdelHakiim
相关产品推荐
相关产品推荐

