为值类型实现operator ++的正确方法是什么?

时间:2015-12-17 19:17:15

标签: c# struct operator-overloading operators increment

我正在使用Number结构的自定义实现,使用非常不同的方式存储和操作数值。

结构是完全不可变的 - 所有字段都实现为readonly

我正在尝试实施++--运算符,而且我遇到了一点混乱:
你如何完成任务?
或者平台是否自动处理此问题,我只需要返回n + 1

public struct Number
{
    // ...
    // ... readonly fields and properties ...
    // ... other implementations ...
    // ...

    // Empty placeholder + operator, since the actual method of addition is not important.
    public static Number operator +(Number n, int value)
    {
        // Perform addition and return sum
        // The Number struct is immutable, so this technically returns a new Number value.
    }

    // ERROR here: "ref and out are not valid in this context"
    public static Number operator ++(ref Number n)
    {
        // ref seems to be required,
        // otherwise this assignment doesn't affect the original variable?
        n = n + 1;
        return n;
    }
}

编辑:我认为这不是关于增量和减量运算符的其他问题的重复,因为这涉及与此上下文中的类行为不同的值类型。我理解类似的规则适用于++--,但我相信这个问题的背景是不同的,并且有足够的细微差别,可以独立存在。

4 个答案:

答案 0 :(得分:9)

  

结构是完全不可变的 - 所有字段都实现为readonly

好!

  

我正在尝试实施++--运营商,而且我有点困惑:你如何执行任务?

你不是。记住++运算符的作用。无论是前缀还是后缀:

  • 获取操作数的原始值
  • 计算后继者的价值
  • 存储继任者
  • 生成原始值或后继者

C#编译器不知道如何为您的类型执行该过程的唯一部分是"计算后继者",以便覆盖++运算符应该是什么做。只是回归继任者;让编译器处理如何进行分配。

  

或者平台是否自动处理此问题,我只需要返回n + 1

是的,那样做。

答案 1 :(得分:1)

++--运算符的处理在C#语言规范中描述,第7.7.5节前缀增量和减量运算符:

  

++ x或--x形式的前缀增量或减量操作的运行时处理包括以下步骤:

     

•如果x被归类为变量:

     

o x被评估以产生变量。

     

o调用所选运算符,并将x值作为其参数。

     

o运算符返回的值存储在x。

评估给出的位置      

o操作员返回的值将成为操作的结果。

因此,这些运算符的自定义重载只需要生成递增/递减的值。其余的由编译器处理。

答案 2 :(得分:0)

Number类将具有某种属性值。

public static Number operator ++(Number n)
{
    // ref seems to be required,
    // otherwise this assignment doesn't affect the original variable?
    n.value = n.value + 1;
    return n;
}

这应该做你想要的。

我使用你的struc写了这个并添加了value属性。

private static void Main(string[] args)
{
    var x = new Number();
    x.value = 3;
    x++;
    Console.WriteLine(x.value);
    Console.Read();
}

这恰当地产生了4

答案 3 :(得分:0)

声明num++;本身会扩展为num = PlusPlusOperator(num);。由于您的数据类型是不可变的,只需return n+1;,编译器将处理其余的数据。