代码之家  ›  专栏  ›  技术社区  ›  Arnis Lapsa

C隐式转换和==运算符

  •  7
  • Arnis Lapsa  · 技术社区  · 16 年前

    一些上下文代码:

    class a
    {
    
    }
    
    class b
    {
        public a a{get;set;}
        public static implicit operator a(b b)
        {
            return b.a;
        }
    }
    
      a a=null;
      b b=null;
      a = b;
    
      //compiler: cannot apply operator '==' to operands of type tralala...
      bool c = a == b; 
    

    是否可以在不同的类型实例上使用==运算符,其中一个实例可以隐式转换为另一个实例?我错过了什么?

    编辑:
    如果类型必须是相同的调用==,那么为什么

    int a=1;
    double b=1;
    bool c=a==b; 
    

    作品?

    5 回复  |  直到 7 年前
        1
  •  14
  •   Community CDub    7 年前

    这个 implicit 操作员只为分配工作。

    你想让平等超载( == )操作员,例如:

    class a
    {
        public static bool operator ==(a x, b y)
        {
            return x == y.a;
        }
    
        public static bool operator !=(a x, b y)
        {
            return !(x == y);
        }
    }
    
    class b
    {
        public a a{get;set;}
        public static implicit operator a(b b)
        {
            return b.a;
        }
    }
    

    这样,您就可以比较两个类型的对象 a b 正如你在文章中所建议的。

    var x = new a();
    var y = new b();
    bool c = (x == y); // compiles
    

    注:

    我建议简单地覆盖 GetHashCode Equals 方法,正如编译器警告的那样,但由于您似乎想抑制它们,可以按如下方式执行。

    更改您的班级声明 到:

    #pragma warning disable 0660, 0661
    class a
    #pragma warning restore 0660, 0661
    {
        // ...
    }
    
        2
  •  11
  •   Eric Lippert    16 年前

    是否可以使用==operator on 不同类型的实例,其中一个 是否可以隐式转换为另一个?

    对。

    我错过了什么?

    这是规范的相关部分。您错过了突出显示的单词。

    预定义的引用类型相等 运算符需要两个操作数 是引用类型值还是 文字空。此外,A 标准 隐式转换存在于 操作数类型与类型 另一个操作数。

    用户定义的转换是根据定义而不是标准转换。这些是引用类型。因此,预定义的引用类型相等运算符不是候选运算符。

    如果类型必须相同,则调用==, 那么为什么[double==int]有效呢?

    您认为类型必须相同的假设是不正确的。有一个从int到double的标准隐式转换,并且有一个取两个double的相等运算符,所以这是可行的。

    我想你也错过了这一点:

    使用 预定义的引用类型相等 用于比较两个引用的运算符 众所周知,在 编译时间。例如,如果 操作数的编译时类型为 两类A和B,如果 A和B都不是源于 其他的,那就不可能 两个操作数引用相同的 对象。因此,操作是 认为是编译时错误。

        3
  •  1
  •   RobV    16 年前

    我可以想象,对于您感兴趣的类型,您实际上需要重写==操作符。即使类型是可隐式转换的,编译/运行时是否仍然会抱怨,这是您必须尝试的事情。

    public static bool operator ==(a a, b b)
        {
            //Need this check or we can't do obj == null in our Equals implementation
            if (((Object)a) == null)
            {
                return false;
            }
            else
            {
                return a.Equals(b);
            }
        }
    

    或者,只需使用Ole6ka建议的Equals实现,并确保实现满足您需要的类型转换。

        4
  •  0
  •   A. M.    16 年前

    http://msdn.microsoft.com/en-us/library/8edha89s.aspx

    在每种情况下,必须有一个参数 与类或结构的类型相同 声明运算符(…)

        5
  •  -1
  •   ole6ka    16 年前

    用这个

     bool c = a.Equals(b);