Make object copy without reference

I have this code and I want to make a copy of characters[currentCharacter]without a memory reference. Do i have to copy the value of each variable individually?

public void Choose(object _info)
        {
            choosing = false;
            characters[currentCharacter].SetDimentions(new Vector2(80,80));
            world = new World(characters[currentCharacter]);
        }
public class Character : Unit
    {
        protected _Keyboard keyboard;
        protected string name;
        protected string description;
        protected bool shield;
        protected double currentTime;
        protected float cooldown;
        protected bool readyToShoot;


        public Character(string _path, Vector2 _position, Vector2 _dimensions, int _ownerId, List<Projectile> _projectiles) : base(_path, _position, _dimensions, _ownerId)
        {
            keyboard = new _Keyboard();
            shield = false;
            readyToShoot = true;
            
           
        }

        public string GetName()
        {
            return name;
        }

        public string GetDescription()
        {
            return description;
        }

        public void SetShieldStatus(bool _status)
        {
            shield = _status;
        }
        public bool HasShield()
        {
            return shield;
        }



        public virtual void Update(Vector2 _offset,PassObject _scroll,MapManager map, List<Projectile> _projectiles)
        {
            bool checkScroll = false;
            int mapTileX, mapTileY, tileType;

            keyboard.Update();
            if (keyboard.GetPress("A"))
            {
                mapTileX = (int)((position.X - speed) / map.GetTiles().GetTilesWidht());
                 mapTileY = (int)(position.Y / map.GetTiles().GetTilesHeight());
                 tileType = map.GetTileType(mapTileX, mapTileY);

                if(map.GetTiles().GetTile(tileType).UnitCross())
                {
                    SetPosition(new Vector2(position.X - speed, position.Y));
                    checkScroll = true;
                }
                
            }
            if (keyboard.GetPress("D"))
            {
                mapTileX = (int)((position.X + speed) / map.GetTiles().GetTilesWidht()) +1;
                mapTileY = (int)(position.Y / map.GetTiles().GetTilesHeight());
                Debug.WriteLine("TILE X: " + mapTileX);
                tileType = map.GetTileType(mapTileX, mapTileY);

                if (map.GetTiles().GetTile(tileType).UnitCross())
                {
                    SetPosition(new Vector2(position.X + speed, position.Y));
                    checkScroll = true;
                }
                    
            }
            if (keyboard.GetPress("W"))
            {
                mapTileX = (int)position.X / map.GetTiles().GetTilesWidht();
                mapTileY = (int)(position.Y - speed) / map.GetTiles().GetTilesHeight();
                tileType = map.GetTileType(mapTileX, mapTileY);

                if (map.GetTiles().GetTile(tileType).UnitCross())
                {
                    SetPosition(new Vector2(GetPosition().X, GetPosition().Y - speed));  //Y is inverted, this means that 0 is on top .So if the player wants to go up Y has do decrease 
                    checkScroll = true;
                }
                   
            }

            if (keyboard.GetPress("S"))
            {
                mapTileX = (int)position.X/ map.GetTiles().GetTilesWidht();
                mapTileY = (int) (position.Y + speed) / map.GetTiles().GetTilesHeight() + 1;
                tileType = map.GetTileType(mapTileX, mapTileY);

                if (map.GetTiles().GetTile(tileType).UnitCross())
                {
                    SetPosition(new Vector2(GetPosition().X, GetPosition().Y + speed));   //Again, Y is inverted
                    checkScroll = true;
                }
                    
            }

            if (checkScroll)
            {
                _scroll(GetPosition());
            }

            keyboard.UpdateOld();
            mouseControl.Update();


            SetRotation(RotateTowards(GetPosition(), new Vector2(mouseControl.newMousePos.X, mouseControl.newMousePos.Y) - _offset));
            mouseControl.UpdateOld();
        }

       



        public override void Draw(Vector2 _offset)
        {
            base.Draw(_offset);
        }

    }

Jip.

Often a method Clone() is made for that.

btw. you can use “properties”. This is a compact way to do what you are doing with all those get and set methods.

for instance:

public string Name { get; protected set; }

… is just like having a public getName() and protected setName(), but shorter :slight_smile: The setter is protected because it explicitly says so, else it would take the public from the beginning of the line, just like “get” is doing.

and then you can make aquite compact clone method:

public Character Clone() 
{
  return new Character 
  {
    Name = this.Name,
    Description = this.Description,
    // etc
  }
}
1 Like

Might not be a bad idea to implement the ICloneable interface as well :slight_smile:

To answer the OP’s question…

Fundamentally, yes you do. If you want to get clever about it you can use reflection to programmatically discover, and copy, fields on an object. I’ve seen your posts around here though and it looks like you’re doing this for a school project. It’s probably not worth it to create an elegant solution for a project you’re going to submit and then probably not have to maintain.

Tomas_Vantroyen’s suggestion above is probably the best way to go. Just good to know what your options are :slight_smile:

Ended up solving it by implementig a new constructor that receives another Character

There’s also a way to do it by using binary serialization to a memory stream to essentially copy the memory, but I favor the Clone approach, myself. A constructor that takes another Character is essentially the same thing as a clone method. The real difference is that you take a Character as an argument and don’t return anything, or you add a Clone method that returns a Character. The only other question is whether or not you gain anything from implementing ICloneable. That’s not a particularly widely useful interface, but when you need it, you tend to really need it.

As i know you are tying to learn this for school read this if you want you want to understand it.