C#编译器创建ref类

时间:2013-07-01 13:40:43

标签: c# .net-4.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 ...

有人能告诉我导致这种行为的原因是什么吗?或者至少如何解决这种行为......

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

你的'位置'类是'参考类型' 当你将pos2等于pos1时,它指向相同的内存位置。

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

答案 2 :(得分:1)

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

您想要像这样调用复制构造函数:

var pos2 = new Position(pos1);