简体   繁体   English

C#,多个==运算符重载,没有模糊的空值检查

[英]C#, multiple == operator overloads without ambiguous null check

Introduction : 简介
I have a few classes which do the same work, but with different value types (eg Vectors of floats or integers). 我有几个类做同样的工作,但有不同的值类型(例如浮点数或整数的向量)。
Now I want to be able to check for equality, this equality should also work in between the types (such as vectorF == vectorI). 现在我希望能够检查相等性,这种相等性也应该在类型之间起作用(例如vectorF == vectorI)。
Also, it should be possible to do a null check (vectorF == null). 此外,应该可以进行空检查(vectorF == null)。

Approach : 方法
My approach is to create multiple overloads for the == and != operators, one for each possible combination. 我的方法是为==和!=运算符创建多个重载,每个可能的组合一个。

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
    [...]
}

Problem : 问题
Using multiple overloads, I cannot just do a null check with the == operator, as the call would be ambiguous. 使用多个重载,我不能只使用==运算符进行空检查,因为调用将是不明确的。

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

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

I'm aware of the possibility to use a ReferenceEquals or null casting instead, but that approachis a serious restriction for me. 我知道有可能使用ReferenceEquals或null cast,但这种方法对我来说是一个严重的限制。

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.
[...]

Question : 问题
Is there a way to implement the == operator in a way, that it allows the simple null check, and allows for equality check between the different vectors? 有没有办法以某种方式实现==运算符,它允许简单的空检查,并允许在不同的向量之间进行相等性检查?

Alternatively, is there another way how I could/should implement this? 或者,我是否可以/应该如何实现这一点?

I'd push back on the whole design to begin with. 我会从一开始就推迟整个设计。 I would never implement == with value semantics between different types, I'd find it rather confusing: instaceTypedA == instanceTypedB yells reference equality (at least to me). 我永远不会在不同类型之间用值语义实现== ,我发现它相当混乱: instaceTypedA == instanceTypedB大喊引用相等(至少对我而言)。

If you need this to work, then implement an implicit conversion between VectorI and VectorF . 如果需要这个,那么在VectorIVectorF之间实现隐式转换。 This is how the framework works. 这就是框架的工作原理。 When you do the following: 执行以下操作时:

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

An oveload ==(int, double) isn't magically produced. oveload ==(int, double)不是神奇地产生的。 What happens is that i is implicitly converted to double and ==(double, double) is invoked. 会发生什么是i被隐式转换为double并且调用了==(double, double)

You can turn around the comparison by using is : 您可以使用is来转换比较:

if (v is VectorF)

This check will fail if v is null . 如果vnull则此检查将失败。

What I would do in this case it not to overload the == operator, and instead do something like: 在这种情况下我会做的是不要重载==运算符,而是执行以下操作:

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...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM