18

简介
我有几个类做同样的工作,但具有不同的值类型(例如浮点数或整数向量)。
现在我希望能够检查相等性,这种相等性也应该在类型之间起作用(例如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
    [...]
}

问题
使用多个重载,我不能只使用 == 运算符进行空检查,因为调用会模棱两可。

var v = new VectorF([...]);

if (v == null)    // This call is ambiguous
[...]

我知道可以使用 ReferenceEquals 或 null 强制转换,但这种方法对我来说是一个严重的限制。

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 检查,并允许在不同向量之间进行相等检查?

或者,还有另一种方法我可以/应该如何实现这个?

4

3 回答 3

20

我会从一开始就推回整个设计。我永远不会==在不同类型之间实现值语义,我会觉得它相当混乱:instaceTypedA == instanceTypedB大喊引用相等(至少对我来说)。

如果您需要此功能,请在VectorIand之间实现隐式转换VectorF。这就是框架的工作原理。当您执行以下操作时:

int i = 1;
double d = 1;
var b = i == d;

超载==(int, double)并不是神奇地产生的。发生的事情i是隐式转换为double并被==(double, double)调用。

于 2017-02-21T10:51:45.183 回答
7

您可以使用以下方法扭转比较is

if (v is VectorF)

v如果是,此检查将失败null

于 2017-02-21T10:43:13.953 回答
3

在这种情况下,我会做的不是使==运算符重载,而是执行以下操作:

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...
}
于 2017-02-21T10:43:42.697 回答