为什么相等性检查不允许对象类型的隐式转换,而允许int类型的隐式转换?

本文关键字:转换 类型 int 检查 对象 为什么 不允许 | 更新日期: 2023-09-27 18:17:19

为什么c#允许隐式地将对象转换为int进行相等比较,而不允许将对象类型转换为对象类型比较,即使存在隐式操作符?

bool errorHere = valueOnly == valuePair;行给出了底部的异常。

class Program
{
    static void Main(string[] args)
    {
        ValueOnly valueOnly = new ValueOnly();
        ValuePair valuePair = new ValuePair();
        bool areEqual = valueOnly.Value == valuePair;
        bool errorHere = valueOnly == valuePair;
        bool butNotHere = valueOnly == (ValueOnly)valuePair;
        valueOnly = valuePair; // Or Here
    }
}
public class ValuePair
{
    public int Value { get; set; }
    public string Text { get; set; }
    public static implicit operator ValueOnly(ValuePair valuePair) {
        if (valuePair.Text != null || valuePair.Value != 0) {
            return new ValueOnly() { Value = valuePair.Value };
        }
        return null;
    }
    public static implicit operator int(ValuePair valuePair) {
        return valuePair.Value;
    }
}
public class ValueOnly
{
    public int Value { get; set; }
}

错误如下:

Error   Operator '==' cannot be applied to operands of type 'ValueOnly' and 'ValuePair'

为什么相等性检查不允许对象类型的隐式转换,而允许int类型的隐式转换?

c#绝对不允许出于任何目的将对象隐式地转换为int。我不确定你指的是不是

那一行
bool butNotHere = valueOnly == (ValueOnly)valuePair; 

表示"允许"这样的转换。如果是这样,它不会做任何这样的事情。它只是调用您自己的转换操作符(如果我正确阅读代码将返回null,因为值将是默认构造的整数),然后在两个对象之间进行引用比较(计算false,因为null不等于任何引用)。

不言而喻,一旦定义了隐式转换操作符,c#将在必要时使用它。因此,我认为你的问题必须更多地了解相等运算符是如何基于其参数的类型工作的,而不是其他任何事情。

关于valueOnly == valuePair检查的更新:

c#规范7.10.6(引用类型相等操作符)规定:

使用预定义的引用类型是绑定时错误相等操作符用于比较两个已知相等的引用在绑定时不同。例如,如果绑定时间类型为操作数是两个类类型A和B,如果既不是A也不是B从另一个衍生,那么这两个就不可能操作数引用同一对象。因此,操作为考虑绑定时间错误。

如果您希望能够比较类类型的对象是否相等,最好的方法是实现IEquatable<T>接口,并根据IEquatable<T>.Equals重写object.Equals(这意味着您还必须重写object.GetHashCode)来匹配。

然而,在比较项目时依赖"隐藏"转换是一个坏主意。如果我们讨论的是比较不相关的类,那么通过尽可能突出比较,您将为自己省去很多痛苦。为此,我建议使用低技术含量的

if(valuePair.Value == valueOnly.Value)

要允许valueOnly == valuePair,您必须将此添加到valuePair类:

public static bool operator == (ValueOnly valueOnly, ValuePair valuePair){
    ValueOnly value = valuePair;
    return valueOnly.Value == value.Value;
}

这使用隐式转换,然后执行我正在寻找的相等性检查…

现在我想到了,隐式转换是愚蠢的(因为我没有为ValueOnly类提供相等操作符):

public static bool operator == (ValueOnly valueOnly, ValuePair valuePair){
    return valueOnly.Value == valuePair.Value;
}