Копия экземпляра C # / Передача объекта ссылка отличается от Java? - PullRequest
4 голосов
/ 26 июня 2011
class Player
{
   private Location location;

   public Location getLocation()
   {
        return location;
   }

    public void setLocation(Location location)
    {
        this.location = location;
    }
}

...

class Location
{
    int x,y,z;

    public Location(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Location(Location location)
    {
        this.x = location.x;
        this.y = location.y;
        this.z = location.z;
    }


    public void updateLocation(Location location) //the fix..
    {
        this.x = location.x;
        this.y = location.y;
        this.z = location.z;
    }
}

Скажите .. вы делаете

Player p1 = new Player();
Player p2 = new Player();
p1.setLocation(p2.getLocation());

Теперь ошибка / проблема возникает, когда вы пытаетесь изменить местоположение других людей.Расположение обоих игроков меняется абсолютно одинаково, так как они оба теперь находятся в одном и том же месте.

Так что, конечно, это ниже будет работать очень хорошо.

p1.setLocation(new Location(p2.getLocation()));

, но проблема в том, что он всегда создаетновый объект .. когда я мог просто обновить существующий экземпляр ..?Как мне обновить существующий экземпляр по умолчанию, не создавая свои собственные методы, как я делал ниже, чтобы это исправить.

Мне пришлось исправить это, используя метод ниже (любой способ сделать это по умолчанию, не делая это ниже))

    public void setLocation(Location location)
    {
        if (this.location == null)
            this.location= new Location(location);
        else
            this.location.updateLocation(location);
    }

Кто-нибудь знает какие-то хитрости, о которых я не знаю?Благодаря.

Ответы [ 2 ]

7 голосов
/ 26 июня 2011

Классы являются ссылочными типами. Когда вы звоните это:

p1.setLocation(p2.getLocation());

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

this.location = location;

Вы назначаете ссылку, а не данные. Это означает, что и location, и this.location будут указывать на один и тот же блок в памяти.

Это важный момент в программировании на C #. Если вы хотите, чтобы данные копировались вместо ссылок, вы должны использовать структуры вместо классов.

В любом случае, переназначение значений из одного экземпляра в другой является довольно распространенной задачей.

Edit:

Вы указали, что не хотите создавать новый объект из-за накладных расходов.

  • Преждевременная оптимизация - источник зла
  • Оптимизируйте, где это имеет смысл и где вы видите, что это действительно снижает производительность. Здесь у вас есть некоторые значения для создания экземпляров объектов на простых ноутбуках.

Также странно говорить, что вам не нравятся свойства - вы программируете на C #, поэтому используйте его правильно, иначе ваши коллеги не будут вам нравиться.

0 голосов
/ 29 июня 2011

Передача ссылок в .NET по сути такая же, как в Java. Однако .NET у нас есть несколько дополнительных функций.

Например, параметры out и ref могут использоваться для возврата значений, переданных в качестве аргументов. например

    public void SaveProductFeature(ref SaveCollection save)
    {
       SaveCollection.Product.ProductId = Product.Save(SaveCollection.Product);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...