-5

突然野生のバグが現れたとき、私はいくつかのコードを掘り下げていました...

じゃあ始めよう。解析中にスクリプト内の位置を表すために、このコードを作成しました。

/// <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.Char の値も変更します... C# からのこの動作はわかりません。他のクラスは同じように動作します。

コピー コンストラクターは役に立ちませんでした。

.NET 4.5 と VS 2012 Update 3 を使用しています...

誰かがこの動作の原因を教えてもらえますか? または、少なくともこの動作を回避する方法...

4

3 に答える 3

3

pos1新しいオブジェクトへの参照です。に設定pos2するpos1と、同じオブジェクトへの 2 つの参照が作成されます。2 つの異なるオブジェクトが必要な場合は、次のようにする必要があります。

var pos1 = new Position();  // Create a new object
var pos2 = new Position(pos1);  // Use your copy constructor
pos2.Char = 10;
于 2013-07-01T13:43:36.127 に答える
1

「Position」クラスは「参照型」です。pos2 を pos1 に等しくすると、同じメモリ位置を指します。

同じオブジェクトであるため、1 つのオブジェクトのプロパティを変更すると、他のオブジェクトも変更されます。

于 2013-07-01T13:43:14.607 に答える
1

これはバグではありません。これは正しい C# の動作です。Positionclass、参照型です。割り当てvar pos2 = pos1;は何もコピーしません。同じPositionインスタンスへの別の参照を作成するだけです。

次のようにコピー コンストラクターを呼び出します。

var pos2 = new Position(pos1);
于 2013-07-01T13:43:22.873 に答える