使用C#,如何一次重载所有运算符?

Using c#, how can I overload all operators at once?
2021-03-07
  •  译文(汉语)
  •  原文(英语)

我有这样的结构.

public struct Money
{
    private readonly decimal _quantity;

    private Money(decimal qty)
    {
        _quantity = Math.Round(qty, 2);
    }

    public static implicit operator Money(decimal dec)
    {
        return new Money(dec);
    }
}

因为Money我必须重载所有运算符+,-,<,<=,>,> =,==,!=等吗?还是有一种方法也可以接受decimalfor的所有运算符Money?如您所见Money,只有一个字段是_quantity.我希望所有要求的运算符Money都应该返回,就像要求输入_quantity一样.

也许在隐式转换运算符下面重载将解决此问题.

public static implicit operator decimal(Money money)
{
    return money._quantity;
}

我正在创建Money结构,因为我不想decimal在整个项目中使用它.编译器应强迫我使用Money而不是decimal.如果我隐式地使用上面的转换运算符,它将与创建此结构的原因相矛盾.提前致谢...

解决过程1

必须实现所有运营商分别,但可以简化通过inmplementing过程static Compare方法(以模拟<=>运算符,它是不支持通过C#):

public struct Money: IComparble<Money> {
  private readonly decimal _quantity;

  ...

  // C# doesn't have <=> operator, alas...
  public static int Compare(Money left, Money right) {
    if (left._quantity < right._quantity)
      return -1;
    else if (left._quantity > right._quantity)
      return 1;
    else 
      return 0;
  }

  public static Boolean operator == (Money left, Money right) {
    return Compare(left, right) == 0;
  }

  public static Boolean operator != (Money left, Money right) {
    return Compare(left, right) != 0;
  }

  public static Boolean operator > (Money left, Money right) {
    return Compare(left, right) > 0;
  }

  public static Boolean operator < (Money left, Money right) {
    return Compare(left, right) < 0;
  } 

  public static Boolean operator >= (Money left, Money right) {
    return Compare(left, right) >= 0;
  }

  public static Boolean operator <= (Money left, Money right) {
    return Compare(left, right) <= 0;
  } 

  public int CompareTo(Money other) {
    return Compare(this, other);
  }
}
速聊1:
谢谢您的回答德米特里.但是我的运算符重载方法已经具有结构return left._quantity<operator>right._quantity.如果c#支持泛型运算符以及泛型类型,那么我的问题将得到解答.
速聊2:
:是的,有时缺少"<=>"运算符(可以将所有比较组合在一起)和数值类型(用于实现算术)的麻烦.

I have a struct like this.

public struct Money
{
    private readonly decimal _quantity;

    private Money(decimal qty)
    {
        _quantity = Math.Round(qty, 2);
    }

    public static implicit operator Money(decimal dec)
    {
        return new Money(dec);
    }
}

For Money do I have to overload all operators +, -, <, <=, >, >=, ==, !=, etc.? Or is there a way to accept all operators of decimal for Money as well? As you see Money has only one field which is _quantity. I want that all operators asked for Money should return as if it is asked for _quantity.

Maybe overloading below implicit conversion operator will solve the problem.

public static implicit operator decimal(Money money)
{
    return money._quantity;
}

I am creating Money struct, because I do not want to use decimal in my entire project. Compiler should force me to use Money instead of decimal. If I use above conversion operator implicitly, it wil contradict the reason behind creating this struct. Thanks in advance...

Solutions1

You have to implement all the operators separately, but you can simplify the process by inmplementing static Compare method (in order to emulate <=> operator which is not supported by C#):

public struct Money: IComparble<Money> {
  private readonly decimal _quantity;

  ...

  // C# doesn't have <=> operator, alas...
  public static int Compare(Money left, Money right) {
    if (left._quantity < right._quantity)
      return -1;
    else if (left._quantity > right._quantity)
      return 1;
    else 
      return 0;
  }

  public static Boolean operator == (Money left, Money right) {
    return Compare(left, right) == 0;
  }

  public static Boolean operator != (Money left, Money right) {
    return Compare(left, right) != 0;
  }

  public static Boolean operator > (Money left, Money right) {
    return Compare(left, right) > 0;
  }

  public static Boolean operator < (Money left, Money right) {
    return Compare(left, right) < 0;
  } 

  public static Boolean operator >= (Money left, Money right) {
    return Compare(left, right) >= 0;
  }

  public static Boolean operator <= (Money left, Money right) {
    return Compare(left, right) <= 0;
  } 

  public int CompareTo(Money other) {
    return Compare(this, other);
  }
}
Talk1:
Thank you for your answer Dmitry. But my operator overload methods already have the structure return left._quantity<operator>right._quantity. If c# have supported generic operators as well as generic types, then my question would have an answer.
Talk2:
: Yes, the absence of "<=>" operator (which can combine all the comparisons) and Numeric type (for implementing arithmetics) is sometimes annoying.
转载于:https://stackoverflow.com/questions/23053888/using-c-how-can-i-overload-all-operators-at-once

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入