2013-07-01 2 views
-5

Я копал какой-то код, когда вдруг появилась дикая ошибка ...C# компилятор создает класс ref

Хорошо, давайте начнем. Я создал этот код для представления позиции в скрипте во время разбора.

/// <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 ...

Может кто-нибудь сказать мне, что вызывает такое поведение? Или atleast, как получить arround такое поведение ...

+2

Это просто ссылочный тип. – Cybermaxs

+3

Это ожидаемое поведение. Классы называются «ссылочными типами» по определенной причине ... – digEmAll

ответ

1

Ваш класс «Тип» - это тип пометок Когда вы равны pos2 to pos1, он указывает на то же место в памяти.

Изменение свойства одного объекта, таким образом, изменить другую, также как и тот же объект

1

Это не ошибка; это правильное поведение C#. Position - class, который является ссылочным типом. Назначение var pos2 = pos1; ничего не копирует, оно просто создает другую ссылку на тот же экземпляр Position.

Вы хотите назвать свой конструктор копирования, как это:

var pos2 = new Position(pos1); 
3

pos1 является ссылкой на новый объект. Установив pos2 на номер pos1, теперь у вас есть две ссылки на один и тот же объект. Если вы хотите два разных объекта, вы должны сделать

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

Это не помогло. Я снова тестирую его. – bash0r

+0

Ничего себе, я не знаю почему, но теперь он работает. Наверное, C++ оставил урон ... – bash0r