C#,多个 == 运算符重载,没有模糊的 null 检查
C#, multiple == operator overloads without ambiguous null check
简介:
我有几个 类 做同样的工作,但具有不同的值类型(例如,浮点数或整数向量)。
现在我希望能够检查相等性,这种相等性也应该在类型之间起作用(例如 vectorF == vectorI)。
此外,应该可以进行空检查(vectorF == null)。
方法:
我的方法是为 == 和 != 运算符创建多个重载,每个可能的组合一个。
public sealed class VectorF
{
[...]
public static bool operator == (VectorF left, VectorI right)
{
// Implementation...
}
public static bool operator == (VectorF left, VectorF right)
{
// Implementation...
}
// Same for != operator
[...]
}
问题:
使用多个重载,我不能只使用 == 运算符进行 null 检查,因为调用会产生歧义。
var v = new VectorF([...]);
if (v == null) // This call is ambiguous
[...]
我知道可以改用 ReferenceEquals 或空转换,但这种方法对我来说是一个严重的限制。
var v = new VectorF([...]);
if(object.ReferenceEquals(v, null)) // Would work, is not user friendly.
[...]
if(v == (VectorF)null) // Would also work, is neither user friendly.
[...]
问题:
有没有办法以某种方式实现 == 运算符,它允许简单的 null 检查,并允许在不同向量之间进行相等性检查?
或者,我 could/should 有没有另一种实现方法?
您可以使用 is
:
扭转比较
if (v is VectorF)
如果 v
为 null
,此检查将失败。
在这种情况下我会做的是不重载 ==
运算符,而是做类似的事情:
public static bool operator == (VectorF left, object right) {
if (object.ReferenceEquals(null, right)) {
// handle null case
}
VectorF rightF = right as VectorF;
if (!object.ReferenceEquals(null, rightF)) {
// Compare VectorF
}
VectorI rightI = right as VectorI;
if (!object.ReferenceEquals(null, rightI)) {
// Compare VectorI
}
// and so on...
}
一开始我会反对整个设计。我永远不会在不同类型之间使用值语义实现 ==
,我发现它相当混乱:instaceTypedA == instanceTypedB
大喊引用相等(至少对我而言)。
如果你需要它工作,那么在 VectorI
和 VectorF
之间实现隐式转换。这就是框架的工作原理。当您执行以下操作时:
int i = 1;
double d = 1;
var b = i == d;
过载 ==(int, double)
并不是神奇产生的。发生的事情是 i
隐式转换为 double
并调用 ==(double, double)
。
简介:
我有几个 类 做同样的工作,但具有不同的值类型(例如,浮点数或整数向量)。
现在我希望能够检查相等性,这种相等性也应该在类型之间起作用(例如 vectorF == vectorI)。
此外,应该可以进行空检查(vectorF == null)。
方法:
我的方法是为 == 和 != 运算符创建多个重载,每个可能的组合一个。
public sealed class VectorF
{
[...]
public static bool operator == (VectorF left, VectorI right)
{
// Implementation...
}
public static bool operator == (VectorF left, VectorF right)
{
// Implementation...
}
// Same for != operator
[...]
}
问题:
使用多个重载,我不能只使用 == 运算符进行 null 检查,因为调用会产生歧义。
var v = new VectorF([...]);
if (v == null) // This call is ambiguous
[...]
我知道可以改用 ReferenceEquals 或空转换,但这种方法对我来说是一个严重的限制。
var v = new VectorF([...]);
if(object.ReferenceEquals(v, null)) // Would work, is not user friendly.
[...]
if(v == (VectorF)null) // Would also work, is neither user friendly.
[...]
问题:
有没有办法以某种方式实现 == 运算符,它允许简单的 null 检查,并允许在不同向量之间进行相等性检查?
或者,我 could/should 有没有另一种实现方法?
您可以使用 is
:
if (v is VectorF)
如果 v
为 null
,此检查将失败。
在这种情况下我会做的是不重载 ==
运算符,而是做类似的事情:
public static bool operator == (VectorF left, object right) {
if (object.ReferenceEquals(null, right)) {
// handle null case
}
VectorF rightF = right as VectorF;
if (!object.ReferenceEquals(null, rightF)) {
// Compare VectorF
}
VectorI rightI = right as VectorI;
if (!object.ReferenceEquals(null, rightI)) {
// Compare VectorI
}
// and so on...
}
一开始我会反对整个设计。我永远不会在不同类型之间使用值语义实现 ==
,我发现它相当混乱:instaceTypedA == instanceTypedB
大喊引用相等(至少对我而言)。
如果你需要它工作,那么在 VectorI
和 VectorF
之间实现隐式转换。这就是框架的工作原理。当您执行以下操作时:
int i = 1;
double d = 1;
var b = i == d;
过载 ==(int, double)
并不是神奇产生的。发生的事情是 i
隐式转换为 double
并调用 ==(double, double)
。