0

我需要计算所有选中的复选框,我的意思是使用运算符重载作为这个例子:

public static int operator +(bool b1, bool b2)
{
    int i1 = 0;
    int i2 = 0;

    if (b1) i1 = 1;
    if (b2) i2 = 1;

    return i1 + i2;
}

然后总数将被简单地检索

int countCbx = cbx1.Checked + cbx2.Checked + ...

但它不起作用,我不明白为什么。编译错误是“二元运算符的参数之一必须是包含类型”。逻辑看起来不错,但这是我第一次在示例之外使用运算符重载。

谢谢你的帮助。

4

3 回答 3

6

但它不起作用,我不明白为什么。

因为语言规范是这么说的。编译器基本上给了你原因。

逻辑看起来不错,但这是我第一次在示例之外使用运算符重载。

成员主体的逻辑很好 - 但您不能为任意类型重载运算符。至少有一个操作数(或转换的返回类型)必须是您在其中声明运算符的类型。

C# 5 规范在第 10.10 节中包含此内容:

与其他成员一样,在基类中声明的运算符由派生类继承。因为运算符声明始终要求声明运算符的类或结构参与运算符的签名,所以在派生类中声明的运算符不可能隐藏在基类中声明的运算符。因此,new 修饰符在操作符声明中从来不是必需的,因此也绝不是允许的。

然后在 10.10.1 中强制执行该规则:

以下规则适用于一元运算符声明,其中 T 表示包含运算符声明的类或结构的实例类型:

  • 一元 +、-、! 或 ~ 运算符必须采用 T 或 T 类型的单个参数?并且可以返回任何类型。
  • ...

.... 10.10.2:

以下规则适用于二元运算符声明,其中 T 表示包含运算符声明的类或结构的实例类型:

  • 二元非移位运算符必须采用两个参数,其中至少一个必须具有类型 T 或 T?,并且可以返回任何类型。
  • 二元<<>>运算符必须有两个参数,第一个参数的类型必须是 T 还是 T?而第二个必须有 int 或 int? 类型,并且可以返回任何类型。

...和 ​​10.10.3:

对于给定的源类型 S 和目标类型 T,如果 S 或 T 是可空类型,则令 S0 和 T0 引用它们的基础类型,否则 S0 和 T0 分别等于 S 和 T。仅当满足以下所有条件时,才允许类或结构声明从源类型 S 到目标类型 T 的转换:

  • S0 和 T0 是不同的类型。
  • S0 或 T0 是发生运算符声明的类或结构类型。
  • ...
于 2012-11-20T15:24:01.370 回答
4

你不能仅仅因为语言不允许这样做。加法运算符不能重载以处理bool值,并且由于bool不能隐式转换为任何算术类型(例如在 C++ 中),因此您没有选择余地。

如果要计算复选框的数量,例如可以使用

var count = (new[] { cbx1, cbx2, ... }).Count(cb => cb.Checked);
于 2012-11-20T15:25:28.363 回答
2

编译错误会告诉你究竟出了什么问题。

“二元运算符的参数之一必须是包含类型”

除了要为其重载的类型(或其中一种类型)的定义之外,您不能重载运算符。

我可以建议吗

int countCbx = new[] { cbx1, cbx2, ... }.Count(c => c.Checked);
于 2012-11-20T15:24:47.093 回答