Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# value/reference passing?

Tags:

c#

reference

I have a declared entity of a class, and want to assign different pre-made templates to it without the templates ever changing. Using a const doesn't seem to do the trick.

Example:

Weapon w1;
w1 = Sword; // premade weapon.
w1.reducedamage(1); // for example a debuff

In this case the premade weapon's damage would be decreased, and it would no longer be available as a template. This problem becomes more profound with enemies.

Example:

Enemy enemy;
enemy = enemies[r] // r being a randomly generated integer and enemies a list of enemy templates
Fight(player,enemy); // this method would resolve a fight between the two entities of the type Character.

This problem would not be visible in the player class, since player is a single reference being passed along all the game methods - because there is only one player. Every time the player fights, an enemy template would be "corrupted".

How would I create templates or classes/structs in general that always pass by value, meaning that the properties of a first class would have the same values as a second, without any relationship between the two classes?

The only success I've gotten with this is to create a method that manually copies each attribute of every class that has a template onto another entity of the same class; but this is extremely unpractical since it needs constant upgrading whenever a new class is added, or an old one changed.

like image 452
Isi Avatar asked Aug 01 '26 19:08

Isi


2 Answers

I must be missing something. This seems like a reasonably simple issue that is easily solved by inheritance, perhaps in conjunction with some sort of Factory. First, you don't want to use a reference to a single instance, you want to create a new instance each time so it is a unique object. I prefer classes over structs, but you could easily create a new struct as well. You could use a Factory to create various pre-configured instances of the objects that have pre-defined values. For example, the Sword of Damocles or the Sword of Destiny.

public static class WeaponFactory
{
       public static Weapon CreateSword(SwordType type)
       {
            var sword = new Sword(); // plain, old default sword

            // override properties based on type
            switch (type)
            {
                case SwordType.SwordOfDamocles:
                    sword.FallTime = GetRandomFutureTime();
                    break;
                case SwordType.SwordOfDestiny:
                    sword.Invincible = true;
                    break;
                ...
            }

            return sword;
        }

        ...
}

Alternative using Actions

public static class WeaponFactory
{
      public static Weapon Create<T>(Action<T> decorator) where T : IWeapon, new()
      {
           var weapon = new T();
           decorator(weapon);
           return weapon;
      }

      public static void SwordOfDamocles(Sword sword)
      {
           sword.FallTime = GetRandomFallTime();
      }

      public static void SwordOfDestiny(Sword sword)
      {
           sword.Invincible = true;
      }
}

var weapon = WeaponFactory.Create(WeaponFactory.SwordOfDamocles);
like image 190
tvanfosson Avatar answered Aug 03 '26 09:08

tvanfosson


What you want is object cloning. You can implement it via the ICloneable interface[1]. That requires that you implement your own cloning mechanism though--you have to do the heavy lifting.

However, what you probably should do instead is just have the constructor take a parameter that represents the template you want, and then fill the properties of the object in question based on that template. That's the direction I go when I want to make duplicate things with a base set of values.

like image 35
Jeff Hubbard Avatar answered Aug 03 '26 09:08

Jeff Hubbard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!