当C#比较Nullable<;T>;=null,会发生什么
本文关键字:null 什么 比较 Nullable lt gt | 更新日期: 2023-09-27 18:28:11
当C#将可为null的类型与"null"进行比较时,C#编译器是否首先插入一些代码来检查变量是否有值?
int? fk2=null;
OtherNullable<int> fk3=null;
Console.WriteLine(fk2 == null);
Console.WriteLine(fk3 == null);
在上下文中,我试图弄清楚equality+隐式和显式强制转换应该是什么样子,以便能够比较fk3和null。
假设您按照这里发布的代码实现了Nullable:如何实现Nullable<T>在幕后打字?并称之为OtherNullable<T>
除了val==null在运行时不起作用之外,只需少量修改即可正常工作。
实施:
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct OtherNullable<T> : IEquatable<OtherNullable<T>> where T : struct {
private bool hasValue;
internal T value;
public OtherNullable(T value)
: this() {
this.value = value;
this.hasValue = true;
}
public OtherNullable(T? value) {
this.value = default(T);
this.hasValue = false;
}
public bool HasValue {
get { return this.hasValue; }
}
public T Value {
get {
if (!this.HasValue) {
throw new InvalidOperationException("No Value");
}
return this.value;
}
}
public OtherNullable(bool b) {
this.value = default(T);
this.hasValue = false;
}
public T GetValueOrDefault() {
return this.value;
}
public T GetValueOrDefault(T defaultValue) {
if (!this.HasValue) {
return defaultValue;
}
return this.value;
}
public bool Equals(OtherNullable<T> other)
{
if (!other.HasValue & !this.HasValue)
return true;
else
return other.hasValue.Equals(hasValue) && other.value.Equals(value);
}
public static bool operator ==(OtherNullable<T> left, OtherNullable<T> right) {
return left.Equals(right);
}
public static bool operator !=(OtherNullable<T> left, OtherNullable<T> right) {
return !left.Equals(right);
}
public override bool Equals(object other) {
if (ReferenceEquals(null, other)) return false;
if (other.GetType() != typeof(OtherNullable<T>)) return false;
return Equals((OtherNullable<T>)other);
}
public override int GetHashCode() {
unchecked {
return (hasValue.GetHashCode() * 397) ^ value.GetHashCode();
}
}
public override string ToString() {
if (!this.HasValue) {
return "";
}
return this.value.ToString();
}
public static implicit operator OtherNullable<T>(T value) {
return new OtherNullable<T>(value);
}
public static explicit operator T(OtherNullable<T> value) {
return value.Value;
}
public static implicit operator OtherNullable<T>(Nullable<T> value) {
if (value.HasValue) {
return new OtherNullable<T>(value.Value);
} else {
return new OtherNullable<T>(null);
}
}
}
测试代码(不会编译——以前是这样):
[TestFixture]
public class TestOtherNullable {
[Test]
public void Test()
{
var a = new OtherNullable<int>();
a = 1;
Assert.IsTrue(a.HasValue);
Assert.IsFalse(a == null);
var b = new OtherNullable<int>();
b = null;
Assert.IsTrue(b == null);
}
}
任何Nullable<T>
到null
的相等性检查等价于到!nullable.HasValue
。它没有其他有意义的语义。我不确定OtherNullable<T>
的处理方式,因为它不是标准类型。
Q: ";当C#将可为null的类型与"0"进行比较时;空";,C#编译器先插入一些代码来检查变量是否有值"
A: 编译器不在此实例中插入代码。在这种情况下,Equals运算符被覆盖如下:
public override bool Equals(object other)
{
if (!this.HasValue)
{
return (other == null);
}
if (other == null)
{
return false;
}
return this.value.Equals(other);
}
它确实负责将其与null进行比较。
编译器通过以下方式帮助您:
// this
int? x = null;
// Transformed to this
int? x = new Nullable<int>()
// this
if (x == null) return;
// Transformed to this
if (!x.HasValue) return;
// this
if (x == 2) return;
// Transformed to this
if (x.GetValueOrDefault() == 2 && x.HasValue) return;
所有这些信息都在您链接的问题中。
感谢@barrylloyd和@ChaosPandion