2013-12-13 4 views
-1

Так недавно я обнаружил, что вы можете изменить переменную, передав ее другому объекту класса, а затем изменение вновь полученного значения изменит начальное значение. Я должен извиниться, так как знаю, что я очень плохо объяснил это. Вот мой тест, чтобы узнать, работает ли это, и так оно и было.Пропустить справочные проблемы

класс Программа { статический объектA a; статический объект B b;

static void Main(string[] args) 
    { 
     a = new objectA(); 
     b = new objectB(a); 

     Console.WriteLine(a.v + "\n"); 
     Console.WriteLine(b.b.v + "\n"); 

     a.v = 5; 

     Console.WriteLine(a.v + "\n"); 
     Console.WriteLine(b.b.v + "\n"); 

     b.b.v = 7; 

     Console.WriteLine(a.v + "\n"); 
     Console.WriteLine(b.b.v + "\n"); 

     Console.ReadLine(); 
    } 
} 

class objectB 
{ 
    public objectB(objectA b) 
    { 
     this.b = b; 
    } 

    public objectA b; 
} 

class objectA 
{ 
    public objectA() 
    { 
     v = 0; 
    } 

    public int v; 
} 

Я играл примерно с этим в проекте с участием частиц и двигатель частиц, и она работала прекрасно, но потом я пытался что-то другое, и я немного потерял.

У меня есть класс А, который наследует класс B, который наследуется абстрактного класса C.

Основной класс инициализирует класс А и передает его значение, которое он хранит в классе С.

В отличие от моего теста, когда я редактирую значение в основном классе, значение не изменяется в классе С.

class MainExample { 
private vector2 position = new vector2(175, 135); 
private ship_ShipName ship_(); 
... 
    public MainExample() 
    { 
      ship_ = new ship_ShipName(position); 
      ... 

     } 
} 

class ship_ShipName : Ship 
{ 
    public ship_ShipName(vector2 position) 
    { 
      this.position = position; //this.position being the position from Module.cs 
    } 
} 

class Ship : Module { ... } 
abstract class Module { vector2 position; } 

Глядя на мой двигатель частиц теперь я вижу, что это не абстрактно, так что эта проблема должна относиться к этому. Любое понимание очень ценится, и я прав, чтобы думать, что я описываю, это «передача по ссылке»? Благодарю.

+0

Вы передаете все по значению в коде выше. –

+0

Если вы хотите, чтобы мы проанализировали, почему ваша программа делает то, что она есть, тогда покажите ее нам. Не видя, что вы делаете, мы можем только догадываться, почему вы видите результаты, которых вы не ожидаете. – Servy

ответ

6

В приведенном выше примере кода нет пропущенных ссылок. Вы строите два разных объекта: a и b. Эти объекты независимы, а изменения свойств/полей в одном не отражаются в другом.

Вы можете думать, что эта линия создает ссылку:

b = new objectB(a); 

Это не так. Он создает новый объект, вызывая конструктор objectB, передающий a в качестве аргумента (и он передается по значению).

EDIT на основе OP осветления

Я думаю, что разница между тестовой программой и реальным кодом, публикуемым в том, что в реальном коде, vector2 является struct. Структуры являются значениями типов в C#, в отличие от классов, которые являются ссылочными типами. В вашем тестовом коде, когда вы передали a конструктору для b, аргумент является классом, поэтому ссылочный тип передается по ссылке. В вашем реальном коде создается копия vector2.

Вы можете добавить ключевое слово ref, чтобы передать значение конструктору по ссылке. Тем не менее, копия все равно будет сделана, когда вы назначите ее в свое местное поле. Нет простого способа исправить это. Лучшим способом было бы создать оберточный тип class, который содержит вектор, а затем все стороны сохраняют ссылки на один экземпляр объекта-обертки.

+0

Он передает значение ссылки на 'a' в конструкторе' b'. Вероятно, он присваивает значение верхнего уровня 'a' внутренней переменной, называемой' b' типа 'objectA', и он меняет' v' 'a'. Это отражено в 'b.b.v'. –

+0

Возможно. Невозможно узнать наверняка, если OP не отправит код для классов 'objectA' и' objectB' ... – TypeIA

+0

Я обновил OP полный код. Извините за причинение путаницы и спасибо за помощь, всем. – Anthony

-2

Занятия проходят по ссылке. Они являются указателями на этот класс. Параметры класса не копируются. Поэтому, если вы измените поля этого класса параметров, поля этого класса будут изменены. Существует один экземпляр класса.

Клонирование - это копирование класса (создание двух разных классов).

+0

Нет. Нет «pass-by-reference», если параметр не равен 'ref' или' out'. – newacct

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