当C#将可空类型与“null”进行比较时,C#编译器是否会插入一些代码来检查变量是否首先具有值?
int? fk2=null;
OtherNullable<int> fk3=null;
Console.WriteLine(fk2 == null);
Console.WriteLine(fk3 == null);
上下文,我正在尝试找出相等+隐式和显式转换应该是什么样子来启用fk3和null的比较。
假设您根据此处发布的代码实施了Nullable:How does a Nullable<T> type work behind the scenes?并将其称为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);
}
}
答案 0 :(得分:6)
任何Nullable<T>
与null
的等同检查等效至!nullable.HasValue
。它没有其他语义可行。我不确定与OtherNullable<T>
的交易是什么,因为那不是标准类型。
答案 1 :(得分:2)
问:“当C#将可空类型与”null“进行比较时,C#编译器是否会插入一些代码来检查变量是否首先具有值?”
答:编译器不会在此实例中插入代码。在这种情况下,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;
所有这些信息都在您linked的问题中。
感谢@barrylloyd和@ChaosPandion