C# 编译器创建引用类

本文关键字:引用 创建 编译器 | 更新日期: 2023-09-27 18:20:29

我正在挖掘一些代码,突然出现了一个野生错误......

好的,让我们开始吧。我创建此代码是为了在解析时表示脚本中的位置。

/// <summary>
/// Represents a position in script. (Used for error reporting)
/// </summary>
public sealed class Position
{
    /// <summary>
    /// Line count.
    /// </summary>
    public int Line { get; set; }
    /// <summary>
    /// Character count.
    /// </summary>
    public int Char { get; set; }
    /// <summary>
    /// Index data.
    /// </summary>
    public int Index { get; set; }
    /// <summary>
    /// Initialize new Position object to standard values.
    /// </summary>
    public Position()
    {
        this.Line = 1;
        this.Char = 1;
        this.Index = 0;
    }
    /// <summary>
    /// Copy a Position object.
    /// </summary>
    /// <param name="pos"></param>
    public Position(Position pos)
    {
        this.Line = pos.Line;
        this.Char = pos.Char;
        this.Index = pos.Index;
    }
    /// <summary>
    /// Initialize new Position object to given parameters.
    /// </summary>
    /// <param name="p_index">The index in stream.</param>
    /// <param name="p_line">The line count.</param>
    /// <param name="p_char">The character count</param>
    public Position(int p_index, int p_line, int p_char)
    {
        this.Line = p_line;
        this.Char = p_char;
        this.Index = p_index;
    }
    /// <summary>
    /// Check if 2 Position objects are equal.
    /// </summary>
    /// <param name="p1">Left operand.</param>
    /// <param name="p2">Right operand.</param>
    /// <returns>Returns true, if both position objects are equal.</returns>
    public static Boolean operator ==(Position p1, Position p2)
    {
        return
            p1.Index == p2.Index &&
            p1.Char == p2.Char &&
            p1.Line == p2.Line;
    }
    /// <summary>
    /// Check if 2 Position objects are not equal.
    /// </summary>
    /// <param name="p1">Left operand.</param>
    /// <param name="p2">Right operand.</param>
    /// <returns></returns>
    public static Boolean operator !=(Position p1, Position p2)
    {
        return !(p1 == p2);
    }
    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
    /// <summary>
    /// Equals overload.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public override bool Equals(object obj)
    {
        if (obj is Position)
            return this == (Position)obj;
        return false;
    }
    /// <summary>
    /// ToString override.
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
        return String.Format("{0} - {1} - {2}", this.Index, this.Line, this.Char);
    }
}

但。。。当我做这样的事情时:

var pos1 = new Position();
var pos2 = pos1;
pos2.Char = 10;

然后我更改 pos1 的值。夏亚也...我不知道 C# 中的这种行为。其他类的行为相同。

复制构造函数没有帮助。

我使用 .NET 4.5 和 VS 2012 更新 3...

有人可以告诉我是什么原因导致这种行为吗?或者至少如何绕过这种行为......

C# 编译器创建引用类

pos1是对新对象的引用。通过将 pos2 设置为 pos1 ,您现在有两个对同一对象的引用。如果你想要两个不同的对象,你应该做

var pos1 = new Position();  // Create a new object
var pos2 = new Position(pos1);  // Use your copy constructor
pos2.Char = 10;

您的"位置"类是"引用类型"当您将 pos2 等于 pos1 时,它指向相同的内存位置。

因此,更改一个对象的属性也会更改另一个对象,因为它是同一对象

这不是错误;这是正确的 C# 行为。 Position是一个class,它是一个引用类型。赋值var pos2 = pos1;不会复制任何内容,它只是创建对同一Position实例的另一个引用。

你想像这样调用你的复制构造函数:

var pos2 = new Position(pos1);