2010-01-21 3 views
3

Я чувствую себя довольно невежественным, спрашивая об этом, но кто-нибудь сможет объяснить мне, почему это происходит?Идентификация объекта в .NET

 
class MyClass{ public int i {get; set; } } 
class Program 
{ 
    static void Main(string[] args) 
    { 
     MyClass a = new MyClass(); 
     MyClass b = new MyClass(); 

       b.i = 2; 
     a = b; 
     a.i = 1; 

     Console.Write(b.i + "\n"); //Outputs 1 
    } 
}

Это имеет смысл для меня были я, используя указатели и все, что большие вещи, но я был под впечатлением, что с C#, что «Ъ» будет оставаться независимым от «а».

Я просто использую какую-то ужасно плохую практику? Может быть, кто-то может указать мне на что-то, что объясняет, почему это так на C#?

Спасибо.

ответ

10

Именно эта линия, которая имеет Вы смущены:

a = b; 

Вы ожидали b быть скопирована в a по значению, но на самом деле все, что происходит, вы присвоили ссылку из b в a.

.Net разделяет мир на две категории: ссылочные типы и типы значений (есть также типы делегатов и пара других, но это уже другая история). Любой класс можно определить тип ссылки, и есть несколько важных вещей, чтобы помнить о ссылочных типов:

  • Там нет встроенного способа сделать глубокую копию
  • Будьте осторожны проверки равенства. == предназначен для ссылочного равенства (переменные ссылаются на тот же объект), тогда как .Equals() предназначен для равенства значений, и вам может потребоваться переопределить .Equals() (и GetHashCode()) для вашего типа, чтобы получить это право ,
  • назначение только копирует ссылку (это та часть, которая укусила Вас)
+0

Спасибо, я чувствую себя довольно глупо, но объяснение оценено. – KarlHungus

4

Вы используете указатели после моды. Объект ссылается по ссылке, если только они не сходят с ValueType.

Так

a = b; 

Устанавливает ссылку a равный отношению к b.

1

Не имея указатели не то же самое, как не имеющие ссылки на объекты. В вашем случае «a» является ссылкой на конкретный объект типа MyClass, а также на «b». Когда вы делаете «a = b», вы копируете ссылку, а не объект, поэтому «a» указывает на тот же объект, что и «b».

2

Что вам нужно понять по этому сценарию, так это то, что на самом деле есть 4 объекта, представляющие интерес.

  1. экземпляр # 1 из МойКласса
  2. экземпляра № 2 МойКласса
  3. MyCLASS ссылки на
  4. МойКласса Ссылке б

Изначально ссылки на относится к экземпляру # 1 и ссылка б относится к экземпляр № 2. Это до тех пор, пока вы не выполните линию a=b;. После этой строки как ссылка a, так и ссылка b указывают на экземпляр # 1. Поэтому, когда вы вызываете b.i, вы действительно спрашиваете экземпляр # 1, какое значение имеет значение i. Не экземпляр # 2.

0

a и b - ссылки, поэтому после строки a = b a относится к тому же объекту, что и b (и объект, на который указывает указатель a, больше недоступен). Поэтому, когда вы устанавливаете a.i, вы также обновляете объект, на который ссылается b, следовательно, это изменение.

0

Каждый класс в .NET является ссылочным типом. Это означает, что при создании нового экземпляра он указывает на ссылку в памяти и не сохраняет ее значение.

В вашем случае, вы используете при е в = operator (назначение) вы просто просто связать указатель объекта a alsto к указателю объекта b. После этой операции каждое взаимодействие на объекте будет отражено в orther, поскольку они просто указывают на одно и то же.

Если вам нужно дублировать объект, вам необходимо написать код самостоятельно. Но это еще одна история.

Смежные вопросы