重载的后置自增运算符和ToString方法未按预期顺序执行

编程语言 2026-07-11

我正在编写一个代码生成器。我写了一个用来做缩进的简单类:

internal class Indentation {
    public int Indent {
        get => indent;
        set {
            indent = value;
            indentStr = new string(' ', Size * Indent);
        }
    }
    int Size { get; set; }
    string indentStr;
    private int indent;

    public Indentation(int Size = 4) {
        this.Size = Size;
        indentStr = new string(' ', Size * Indent);
    }

    public override string ToString() {
        return indentStr;
    }

    static public Indentation operator --(Indentation indentation) {
        indentation.Indent--;
        return indentation;
    }
    static public Indentation operator ++(Indentation indentation) {
        indentation.Indent++;
        return indentation;
    }
}

在使用它时,我希望下面两行输出相同:

int i = 4;
Indentation indent = new();
Debug.WriteLine(($"{i}|{indent}|public class ... {{"));
Debug.WriteLine(($"{i++}|{indent++}|public class ... {{"));

然而,我得到的是:

4||public class ... {
4|    |public class ... {

整数值按预期在后置自增之前输出,而缩进在自增之后输出。

有没有办法在自增前强制让缩进输出?我在运算符重载上是不是写错了(我找不到有用的线索,微软的文档也很少)。

解决方案

你的后缀运算符写错了。你不能只是返回同一个对象,你需要返回一个新的对象。

public static Indentation operator --(Indentation indentation)
{
    var temp = new() { Indent = indentation.Indent };
    indentation.Indent--;
    return temp;
}

public static Indentation operator ++(Indentation indentation)
{
    var temp = new() { Indent = indentation.Indent };
    indentation.Indent++;
    return temp;
}

如果你想就地修改而不创建副本,那么你需要一个结构体,并使用一个 ref 参数和一个临时变量。

internal struct Indentation
{
    public int Indent
    {
        get;
        set
        {
            field = value;    // use auto-property
            indentStr = new string(' ', Size * value);
        }
    }

    public int Size { get; }

    string indentStr;

    public Indentation(int indent, int size = 4)
    {
        Size = size;
        Indent = indent;    // will set indentStr
    }

    public override string ToString() => indentStr;

    public static Indentation operator --(ref Indentation value)
    {
        var temp = value;
        value.Indent--;
        return temp;
    }

    public static Indentation operator ++(ref Indentation indentation)
    {
        var temp = value;
        value.Indent++;
        return temp;
    }
}

话说回来,可变结构体通常不是一个好主意,只有在你肯定地知道自己在做什么的高性能场景下才应该使用。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章