在C#中使用System.Nullable<T>
观看以下示例。
int x = 5;
int? y = 3;
int? result = x + y; //no compiler warning
编译器可以判断T
是int
是有意义的,因此它可以使用运算符。
int x = 5;
int? y = 3;
bool result = x == y; //no compiler warning
有意义的是,如果x
为null
,则表达式为false
。编译器并不介意。
现在我正在尝试创建一个类似于Nullable<T>
的课程。我们称之为Lookable<T>
。
[Serializable]
public struct Lookable<T> where T : struct
{
public Lookable(T value)
{
Value = value;
}
public T Value { get; }
public override bool Equals(object other)
{
return other != null && Value.Equals(other);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
return Value.ToString();
}
public static implicit operator Lookable<T>(T value)
{
return new Lookable<T>(value);
}
public static explicit operator T(Lookable<T> value)
{
return value.Value;
}
}
这里的想法直接来自.NET's source code。在我的情况下,我只是省略HasValue
属性。
现在这个例子可行:
int x = 6;
Lookable<int> y = x;
Lookable<int> z = 4;
编译器可以在此推断出类型,因为implicit operator
正确吗?
我不明白的是,这个例子会让编译器不高兴:
int x = 5;
Lookable<int> y = 3;
var result1 = x + y; //compile error
var result2 = x == y; //compile error
编译器给我的信息是:
运算符无法应用于&#39;
int
&#39;类型的操作数。和&#39;Lookable<int>
&#39;。
为什么不呢?为什么Nullable<T>
可以实现?我无法在源代码中找到它。是Lookable<T>
还是可能吗?
答案 0 :(得分:5)
这个代码不在Nullable<T>
中 - 它在C#编译器中,特别是规范中的“提升操作符”,以及它们如何将特别应用于{{1 }}。规范参考在this answer。
您无法在自己的类型中重现System.Nullable<T>
行为。它由编译器和运行时(装箱等)进行特殊处理。