为了账号安全,请及时绑定邮箱和手机立即绑定

立即为所有原始数字数据类型实现运算符覆盖/Equatable<T>?

立即为所有原始数字数据类型实现运算符覆盖/Equatable<T>?

C#
拉丁的传说 2023-09-16 17:49:20
我想实现我自己的 CustomNumber 类,并使用关系运算符将其与所有其他原始数字数据类型(int、long、double、float 等)进行比较。有没有办法同时对所有这些操作符执行此操作,或者我真的必须重写 ==、!=、>、<、>= 和 <= 运算符以及每个单个操作符的 Equals(T other) 方法整数数据类型?我想我知道运算符重载一般是如何工作的,但感觉必须有某种快捷方式才能使我的 CustomNumber 与使用关系运算符的所有原始数字数据类型进行比较,而不是必须为每个运算符重载这 6 个运算符中的每一个单一数据类型,可能很快就会添加大约 100 个重载定义。
查看完整描述

2 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

本身没有捷径,您必须为您想要支持的所有类型实现所有运算符和功能,它无法读懂您的想法。

检查decimal 实施情况。

为了您的理智,您会注意到并非所有内容都需要被覆盖,这是通过隐式运算符的实现来完成的:

public static implicit operator Decimal(byte value)

{

   return new Decimal(value);

}


[CLSCompliant(false)]

public static implicit operator Decimal(sbyte value)

{

   return new Decimal(value);

}


public static implicit operator Decimal(short value)

{

   return new Decimal(value);

}


[CLSCompliant(false)]

public static implicit operator Decimal(ushort value)

{

   return new Decimal(value);

}


public static implicit operator Decimal(char value)

{

   return new Decimal(value);

}


public static implicit operator Decimal(int value)

{

   return new Decimal(value);

}


[CLSCompliant(false)]

public static implicit operator Decimal(uint value)

{

   return new Decimal(value);

}


public static implicit operator Decimal(long value)

{

   return new Decimal(value);

}


[CLSCompliant(false)]

public static implicit operator Decimal(ulong value)

{

   return new Decimal(value);

}



public static explicit operator Decimal(float value)

{

   return new Decimal(value);

}


public static explicit operator Decimal(double value)

{

   return new Decimal(value);

}


public static explicit operator byte(Decimal value)

{

   return ToByte(value);

}


[CLSCompliant(false)]

public static explicit operator sbyte(Decimal value)

{

   return ToSByte(value);

}


public static explicit operator char(Decimal value)

{

   UInt16 temp;

   try

   {

      temp = ToUInt16(value);

   }

   catch (OverflowException e)

   {

      throw new OverflowException(Environment.GetResourceString("Overflow_Char"), e);

   }

   return (char)temp;

}


public static explicit operator short(Decimal value)

{

   return ToInt16(value);

}


[CLSCompliant(false)]

public static explicit operator ushort(Decimal value)

{

   return ToUInt16(value);

}


public static explicit operator int(Decimal value)

{

   return ToInt32(value);

}


[CLSCompliant(false)]

public static explicit operator uint(Decimal value)

{

   return ToUInt32(value);

}


public static explicit operator long(Decimal value)

{

   return ToInt64(value);

}


[CLSCompliant(false)]

public static explicit operator ulong(Decimal value)

{

   return ToUInt64(value);

}


public static explicit operator float(Decimal value)

{

   return ToSingle(value);

}


public static explicit operator double(Decimal value)

{

   return ToDouble(value);

}


public static Decimal operator +(Decimal d)

{

   return d;

}


public static Decimal operator -(Decimal d)

{

   return Negate(d);

}


public static Decimal operator ++(Decimal d)

{

   return Add(d, One);

}


public static Decimal operator --(Decimal d)

{

   return Subtract(d, One);

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static Decimal operator +(Decimal d1, Decimal d2)

{

   FCallAddSub(ref d1, ref d2, DECIMAL_ADD);

   return d1;

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static Decimal operator -(Decimal d1, Decimal d2)

{

   FCallAddSub(ref d1, ref d2, DECIMAL_NEG);

   return d1;

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static Decimal operator *(Decimal d1, Decimal d2)

{

   FCallMultiply(ref d1, ref d2);

   return d1;

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static Decimal operator /(Decimal d1, Decimal d2)

{

   FCallDivide(ref d1, ref d2);

   return d1;

}


public static Decimal operator %(Decimal d1, Decimal d2)

{

   return Remainder(d1, d2);

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static bool operator ==(Decimal d1, Decimal d2)

{

   return FCallCompare(ref d1, ref d2) == 0;

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static bool operator !=(Decimal d1, Decimal d2)

{

   return FCallCompare(ref d1, ref d2) != 0;

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static bool operator <(Decimal d1, Decimal d2)

{

   return FCallCompare(ref d1, ref d2) < 0;

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static bool operator <=(Decimal d1, Decimal d2)

{

   return FCallCompare(ref d1, ref d2) <= 0;

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static bool operator >(Decimal d1, Decimal d2)

{

   return FCallCompare(ref d1, ref d2) > 0;

}


[System.Security.SecuritySafeCritical]  // auto-generated

public static bool operator >=(Decimal d1, Decimal d2)

{

   return FCallCompare(ref d1, ref d2) >= 0;

}


查看完整回答
反对 回复 2023-09-16
?
慕少森

TA贡献2019条经验 获得超9个赞

作为部分快捷方式,您可以限制double覆盖所有常规“数字”类型,但需要编译器插入强制转换。double对于较大的整数值,总是比较是危险的(int并且较小的类型始终是精确的)。


class MyType 

{

    public override bool Equals(object obj)

    {

        return base.Equals(obj);

    }

    public override int GetHashCode()

    {

        return base.GetHashCode();

    }

    public static bool operator == (MyType x, double c)

    {

       // write some real code here - this one does not have a value to compare to. 

       return c > 42; 

    }


    // you need all several overrides for each operator to behave in expected way

    // so calling the same one (a == b)

    // from a != b, b != a, b == a is a way to keep them consistent

    public static bool operator == (double c, MyType x)

    {

        return (x == c);

    }


    public static bool operator != (double c, MyType x)

    {

        return !(c == x);   

    }


    public static bool operator != (MyType x, double c)

    {

        return !(x == c);

    }

}

笔记

  • C#/.NET 没有内置的“数字”类型概念 - 这是人们经常问的问题(即,是否存在将我的泛型方法限制为数字类型的约束?,泛型 - 其中 T 是数字?)。

  • 不要忘记实施IEquatable<T>IComparableIComparable<T>...

  • 考虑一下它是否真的对你的“数字”有用,能够自由地与其他类型混合 - 特别是与不精确float/double已经足够痛苦的比较。


查看完整回答
反对 回复 2023-09-16
  • 2 回答
  • 0 关注
  • 67 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信